next.js에서는 자체적으로 내부에서 api설계가 가능합니다.
server/client component 가 분기되었고 해당 영역에서의 작업이 명확해진 next.js의 app Router에서는
서버설정을 하는 작업은 backend 개발자가 하더라도 간단한 api정도는
front 개발자도 할 수 있어야 개발 효율과 퍼포먼스가 나오게 됩니다.
import API_CODE from "@/const/api_code";
import { repairstudioDB } from "@/nextUtil/dbconfig";
import _ from "lodash";
import { NextRequest, NextResponse } from "next/server";
interface Select {
ORDER_DATE: string;
INTEGRATION_CODE: string;
PRODUCT_NAME: string;
CHANNEL_CODE: string;
SALES_CHANNEL: string;
CNT: number;
}
// 함수명은 POST, GET등 통신을 위한 방식으로 명시해줍니다.
// 또한 req를 반드시 받아야하며 NextRequest는 next에서 제공해주는 타입입니다.
// db connection을 통한 api이기에 promise객체를 비동기 처리해주기 위해 async도 붙여줍니다.
export const POST = async (req: NextRequest) => {
// 서버통신이기에 원할한 에러처리를 위해 try/catch문으로 묶어줍니다.
try {
// 저는 db에서 필요한 데이터를 가져오기위해 SQL 작성을 해줬습니다.
const query = `
SELECT
COUNT(DISTINCT c.member_id) AS 'total',
COUNT(DISTINCT o.member_id) AS 'order_customer',
SUM(CASE WHEN o.last_order_date > DATE_SUB(CURDATE(), INTERVAL 30 DAY) THEN 1 ELSE 0 END) AS 'inThirtyDays',
SUM(CASE WHEN o.last_order_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 3 MONTH) AND DATE_SUB(CURDATE(), INTERVAL 1 MONTH) THEN 1 ELSE 0 END) AS 'oneToThreeMonth',
SUM(CASE WHEN o.last_order_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 6 MONTH) AND DATE_SUB(CURDATE(), INTERVAL 3 MONTH) THEN 1 ELSE 0 END) AS 'threeToSixMonth',
SUM(CASE WHEN o.last_order_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 9 MONTH) AND DATE_SUB(CURDATE(), INTERVAL 6 MONTH) THEN 1 ELSE 0 END) AS 'sixToNineMonth',
SUM(CASE WHEN o.last_order_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 12 MONTH) AND DATE_SUB(CURDATE(), INTERVAL 9 MONTH) THEN 1 ELSE 0 END) AS 'nineToTwelveMonth',
SUM(CASE WHEN o.last_order_date < DATE_SUB(CURDATE(), INTERVAL 12 MONTH) THEN 1 ELSE 0 END) AS 'twelveMonthOver'
FROM
Customersprivacy c
LEFT JOIN
(SELECT member_id, MAX(order_date) AS last_order_date
FROM Orders
GROUP BY member_id) o ON c.member_id = o.member_id;
`;
// 설정해둔 db의 정보를 가져오고
const db = await repairstudioDB.getInstance();
// 작성한 sql문을 기반으로 데이터를 불러옵니다.
const selects: Select[] = await db.query(query);
// 응답값에는 front단에서 받고싶은 형태로 가져온 데이터를 정리해줍니다.
return NextResponse.json({
// 상태코드를 남겨 해당 api의 상태를와 메세지를 주고
...API_CODE[200],
// 객체로 묶어 값을 내려줬습니다.
data: {
data: selects[0],
},
});
} catch (error) {
console.error(error);
// 실패시에는 에러코드를 뱉어 해당 에러에 맞는 메세지랑 코드를 프론트에게 전달 할 수 있습니다.
return NextResponse.json(API_CODE[9000]);
}
};
전체적인 흐름을 주석으로 작성 하였지만 핵심은 다음과 같습니다.
1. GET/POST 로 이름을 작성한다.
2. req를 매개변수로 받고 res를 반환해준다.
물론 req를 무조건적으로 받는건 아니고 예외 적인 API들도 존재합니다.
위 링크처럼 req가 필요없는 동작만을 실행 할 경우에는 굳이 req를 매개변수로 받지 않아도 됩니다.