이번 포스트는 Next.js의 Pages Router에서 제공하는 라우팅 기능중 API Routes에 관해 정리하는 포스트이다. Next.js APP으로 MySQL을 연계하여 데이터를 핸들링 하기 위해 API Routes를 사용해보며 사용방법을 정리하려 한다.
API Routes
Next.js 는 API Routes를 사용하여 서버사이드 로직을 작성하고 API 엔드포인트를 생성하는 기능을 제공한다. API Routes를 사용하면 Next.js 어플리케이션 내에서 백엔드의 역할을 수행하는 API 엔드포인트를 간단하게 만들 수 있다.
1. /pages/api 디렉토리생성
첫번째로 Next.js 어플리케이션 루트 디렉토리 내에서 pages 디렉토리 안에 api 디렉토리를 생성한다. 이 디렉토리는 API Routes 파일을 저장하는 디렉토리이다.
2. API 엔드포인트 파일 생성
디렉토리를 생성한 후 API 엔드포인트 파일을 생성하고 로직을 작성하면 된다.
//HandlePost.tsx
import { NextApiRequest, NextApiResponse } from 'next';
const conn = {
// mysql 접속 설정
host: process.env.CLOUD_MYSQL_HOST,
port: process.env.CLOUD_MYSQL_PORT,
user: process.env.CLOUD_MYSQL_USER,
password: process.env.CLOUD_MYSQL_PASSWORD,
database: process.env.CLOUD_MYSQL_DATABASE_NM,
};
export const handleMySql = async (params) => {
const mysql = require('mysql');
const connection = mysql.createConnection(conn);
await connection.connect();
let result;
.
.
.
//API 로직 작성
connection.query(sql, (error, data, fields) => {
if (error) {
console.error(error);
} else {
result = data;
}
);
connection.end();
return result;
};
export default async function HandlePost(request: NextApiRequest, response: NextApiResponse) {
let params;
if (request.method === 'GET') {
params = request.query;
} else if (request.method === 'POST') {
params = request.body;
}
const result = await handleMySql(params);
response.status(200).json(result);
}
위 코드는 MySQL 과 연동하여 데이터를 핸들링하기 위해 작성한 코드 일부이다.
API 엔드포인트 파일 내에 정의된 핸들러 함수는 HTTP 로 API 요청을 보냈을 경우 첫번째 인자로 HTTP 요청(request)와 두번째 인자로 HTTP 응답(response)를 받게 되는데 Next.js 의 API Routes를 사용했으니 'next' 에서 제공하는 'NextApiRequest' 로 요청을 받고 'NextApiResponse'로 결과값을 담아서 응답을 보내는 방식으로 로직을 작성하였다. 위 코드의 경우 요청을 보낼때 등록 시에는 게시글제목 이나 내용, 조회시에는 게시글의 ID를 파라미터로 받게 되는데 첫번째 인자 request 에서 꺼내서 파라미터를 사용할 수 있다.
GET 으로 요청을 보낸 경우는 reqeust.query, POST 로 요청을 보낸 경우는 request.body 에 파라미터로 보낸 데이터가 담겨있다.
원하는 API 로직을 작성한 후에는 돌려받고자 결과 값을 status 가 200(요청성공) 일때 위 코드와 같이 return 해주면 클라이언트에서 해당 엔드포인트로 요청을 보냈을 때 결과값을 JSON 형식으로 반환한다.
3. Clinet 요청
//Post.tsx
axios.get('/api/HandlePost', { params: param }).then((res) => {
setPosts(res.data)
.
.
. // 반환받은 결과 데이터 처리 로직 작성
});
클라이언트 쪽에서 요청을 보낸 코드의 일부이다. 작성된 API Routes 는 위 코드와 같이 클라이언트에서 '/api/API엔드포인트파일명' 으로 axios나 fetch 로 접근이 가능하다. 결과 값은 data 에 JSON 형식으로 반환한다.
한가지 주의사항은 Next.js 공식 레퍼런스에서는 getServerSideProps 나 getStaticProps 와 같은 서버에서 실행되는 함수 내에서 API Route 사용을 권하지 않고 있다.
getServerSideProps의 경우는 매 요청마다 서버에서 데이터를 가져와서 동적으로 렌더링하기 때문에 API Routes 를 서버쪽에서 사용할 수는 없고 http를 붙여서 사용하면 데이터를 가져올 수는 있다.('http://localhost:3000/api/HandlePost' 이런 식으로 .. ) 하지만 서버에서 외부 API로 데이터를 가져오는 것이 아닌 직접 DB에 붙을 수 있다면 DB 커넥션, 쿼리 실행 및 데이터를 받아오는 함수를 HandlePost.tsx 파일의 handleMySql 함수처럼 따로 분리를 하였다가 getServerSideProps를 사용해야하는 페이지에서 해당 함수만 import하면 http를 따로 붙일 필요 없이 바로 서버에서 직접 데이터를 핸들링 할 수 있다.
getStaticProps의 경우는 빌드시에 실행되는 함수이고 API Routes 는 런타임에 동작하는 엔드포인트로 Next.js에서는 권장하지 않는 방법이다.