Next.js로 public API를 구축할 수 있는 솔루션을 제공
pages/api
폴더 내의 모든 파일은 /api/*
에 매핍되어 페이지 대신 API 엔드포인트로 처리되며 이는 서버 측 전용 번들이며 클라이언트 측 번들 크기를 늘리지 않는다.
import type { NextApiRequest, NextApiResponse } from 'next'
type ResponseData = {
message: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
res.status(200).json({ message: 'Hello from Next.js!' })
}
API 경로에서 다양한 HTTP 메소드를 처리하려면 다음과 같이 요청 핸들러에서 req.method를 사용할 수 있다.
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
// Process a POST request
} else {
// Handle any other HTTP method
}
}
API Routes는 들어오는 요청(req)을 파싱하는 request helpers를 제공한다.
content-type
에 따라 파싱된 bodyServer Response object는 개발자 경험을 개선하고 새로운 API 엔드포인트를 더 빨리 생성할 수 있도록 하기 위해 express.js와 유사한 여러 helper methods를 포함한다.
getStaticProps
를 사용하여 페이지를 다시 검증한다. API Routes는 클라이언트와 서버 간의 데이터를 주고받는 데 유용. 예를 들어, 사용자로부터 폼 데이터를 받아 서버에서 처리할 때 사용할 수 있다.
데이터 무결성 보장: 서버 측 검증은 클라이언트가 어떤 환경에서든지 잘못된 데이터를 서버에 전송하지 못하도록 합니다. 이는 데이터베이스에 저장되는 데이터의 품질과 무결성을 보장하는 데 중요합니다
// pages/api/submit.js
import type { NextApiRequest, NextApiResponse } from 'next'
import { z } from 'zod'
const schema = z.object({
// ...
})
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const parsed = schema.parse(req.body)
// ...
}
API 라우트를 사용하면 클라이언트 사이드에서 바로 외부 API를 호출하지 않고, 내 서버를 거치게 하여 외부 서비스의 URL이나 키 같은 민감한 정보를 숨길 수 있습니다. 이는 보안상의 이점을 갖습니다.
외부 API를 숨기는 것은 보안과 데이터 보호 측면에서 여러 가지 이점을 제공합니다. Next.js API Routes를 사용하여 외부 API 호출을 서버 측에서 처리함으로써 다음과 같은 상황에서 이점을 얻을 수 있습니다:
API 키 보호:
상황: 여러분의 애플리케이션이 외부 서비스(API)를 사용해야 하고, 이 서비스에 접근하기 위해 API 키가 필요하다면, 이 API 키를 클라이언트 코드에 직접 포함시키는 것은 위험할 수 있습니다. 사용자가 API 키를 쉽게 추출할 수 있기 때문입니다.
이점: Next.js API Routes에서 외부 API를 호출함으로써 API 키를 서버 측에 안전하게 보관할 수 있습니다. 클라이언트는 API 키를 전혀 알 필요가 없습니다.
요청 및 응답 변환:
상황: 외부 API의 응답 형식이 클라이언트 애플리케이션에 적합하지 않을 수 있습니다. 예를 들어, 외부 API가 너무 많은 데이터를 반환하거나 필요한 형식으로 데이터를 반환하지 않는 경우가 있습니다.
이점: Next.js API Routes에서 외부 API의 응답을 변환하여 클라이언트가 필요한 데이터만 전달할 수 있습니다. 이를 통해 데이터의 크기를 줄이고 클라이언트의 처리 부담을 줄일 수 있습니다.
보안 및 접근 제어:
상황: 특정 사용자만 외부 API에 접근할 수 있도록 제한해야 하는 경우가 있습니다.
이점: Next.js API Routes에서 사용자 인증 및 권한 검사를 수행한 후에 외부 API를 호출할 수 있습니다. 이를 통해 인증되지 않은 사용자가 외부 API에 접근하는 것을 방지할 수 있습니다.
서버에서 데이터 변환이나 처리가 필요한 경우 API Routes를 사용할 수 있습니다. 예를 들어, 외부 API로부터 데이터를 가져와서 클라이언트에 맞게 변환한 후 제공할 수 있습니다.
클라이언트에서 직접 외부 API를 호출하는 대신, 서버에서 API 요청을 중계하고 응답 데이터를 필터링하거나 가공하여 클라이언트에 전달할 수 있습니다. 이는 네트워크 트래픽을 줄이고, 클라이언트 애플리케이션의 성능을 향상시킬 수 있습니다.
// pages/api/external-data.js
export default async (req, res) => {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
// 데이터 변환
const transformedData = data.map(item => ({
id: item.id,
name: item.name.toUpperCase(),
}));
res.status(200).json(transformedData);
};
API Routes를 통해 사용자 인증 및 권한 관리를 구현할 수 있습니다. 예를 들어, 토큰을 검증하여 사용자가 인증된 상태인지 확인할 수 있습니다.
사용자 인증: 사용자의 로그인 요청을 처리하기 위해 API 라우트를 사용하여 서버측에서 사용자의 인증을 처리하고, 인증 토큰을 클라이언트에 전달할 수 있습니다.
// pages/api/protected.js
import jwt from 'jsonwebtoken';
export default (req, res) => {
const { authorization } = req.headers;
if (!authorization) {
return res.status(401).json({ message: 'No token provided' });
}
try {
const decoded = jwt.verify(authorization.split(' ')[1], 'secret-key');
res.status(200).json({ message: 'Authenticated', user: decoded });
} catch (error) {
res.status(401).json({ message: 'Invalid token' });
}
};
서버 측에서만 사용할 수 있는 특정 기능(예: 파일 시스템 접근, 데이터베이스 쿼리 등)을 API Routes를 통해 제공할 수 있습니다.
// pages/api/upload.js
import formidable from 'formidable';
export default (req, res) => {
if (req.method === 'POST') {
const form = new formidable.IncomingForm();
form.parse(req, (err, fields, files) => {
if (err) {
return res.status(500).json({ message: 'File upload error' });
}
// 예: 파일 처리
// const file = files.file;
// fs.renameSync(file.path, `/uploads/${file.name}`);
res.status(200).json({ message: 'File uploaded successfully' });
});
} else {
res.status(405).json({ message: 'Method not allowed' });
}
};