API 라우트
- next.js 에서는 API 라우트를 만들어 서버리스 함수를 쉽게 구현할 수 있도록 해주는 기능이다. API 라우트를 통해 별도의 서버 설정 없이도 서버 측 로직을 작성하고, 클라이언트 측과 데이터를 주고 받을 수 있다. `pages/api` 디렉토리에서 사용할 수 있으며, 파일 기반의 라우팅 시스템을 따른다.
서버리스 함수(Serverless Functions) : 클라우드 컴퓨팅에서 서버를 직접 관리하지 않고, 코드만 작성하여 클라우드 제공자가 알아서 실행해주는 일종의 서버 측 로직이다. 개발자는 함수 코드 작성에만 집중하고, 클라우드 제공자가 자동으로 서버를 프로비저닝, 확장, 관리하며, 함수가 호출될 때만 비용이 청구되는 방식으로 동작한다.
특징)
자동 확장 : 요청 수에 따라 자동으로 확장된다. 동시에 수백만 건의 요청을 받아도 클라우드 제공자는 이를 처리하기 위해 필요한 리소스를 자동으로 할당한다.
이벤트 기반 실행 : 특정 이벤트에 반응하여 실행한다. 이벤트는 HTTP 요청, 파일 업로드, 데이터베이스 변경, 타이머 등 다양한 트리거에 의해 발생할 수 있다.
기본구조
- API 라우트를 사용하려면 `pages/api` 디렉토리 내에 파일을 생성한다. 이 파일이 API 엔드포인트로 작동한다. 파일 이름이 라우트 경로가 된다.
export default function handler(req, res){
res.status(200).json({ message : 'Hello' });
}
- `/api/hello` 경로에서 `Get` 요청을 받으면 `{ message : 'Hello' }라는 JSON 응답이 반환된다.
HTTP 메서드 처리
API 라우트는 다양한 HTTP 메서드(`GET`, `POST`, `PUT`, `DELETE`)를 처리할 수 있다. 요청 객체 `req`와 응답 객체 `res`를 사용하여 요청 데이터를 받고 처리 결과를 반환할 수 있다.
export default function handler(req, res){
const { method } = req;
switch(method){
case 'GET':
res.status(200).json({message : 'Get request'});
break;
case 'POST':
const data = req.body;
res.status(201).json({message : 'Data received',data});
break;
case 'PUT':
res.status(200).json({message : 'Put request'});
break;
case 'DELETE':
res.status(204).end();
break;
default:
res.setHeader('Allow', ['GET', 'POST', 'PUT', 'DELETE']);
res.status(405).end(`Method ${method} Not Allowed`);
}
}
요청 객체 (req)
`req` (Request 객체) | |
`req.query` | URL 쿼리 파라미터를 포함하는 객체(`/api/data?id=1` -> `req.query.id` 는 `1`) |
`req.body` | 요청 본문에 데이터를 포함(`POST`나 `PUT` 요청 시) |
`req.method` | HTTP 요청 메서드 (`GET, `POST` 등) |
`req.headers` | 요청 헤더를 포함하는 객체 |
응답 객체(res)
`res` (Response 객체) | |
`res.status(code)` | 응답 상태 코드를 설정 (`res.status(200)`) |
`res.json(data)` | JSON 형식으로 응답을 전송 |
`res.setHeader(name,value)` | 응답 헤더를 설정 |
`res.end()` | 응답을 종료 |
동적 API 라우트
API 라우트에서도 페이지와 마찬가지로 동적 라우팅을 사용할 수 있다. 이를 통해 URL의 일부분이 동적으로 변하는 API 엔드포인트를 쉽게 생성할 수 있다.
//pages/api/users/[id].js
export default function handler(req,res){
const { id } = req.query;
res.status(200).json({ userId : id });
}
- URL 경로를 `id` 부분이 동적으로 변하며, 해당 `id`값을 JSON응답으로 반환한다.
API 라우트 활용
- 데이터베이스 작업 : 클라이언트롤부터 데이터를 받아 데이터베이스에 저장하거나, 데이터베이스에서 데이터를 조회하여 클라이언트에 반환하는 작업을 처리할 수 있다.
- 서드파티 API 통신 : 다른 외부 API와 통신하여 데이터를 받아 클라이언트에 제공하거나, 외부 API에 데이터를 전송할 수 있다.
- 인증/인가 작업 : API 라우트에서 인증 토큰을 검증하거나, 사용자 권한을 확인하는 작업을 처리할 수 있다.
API 라우트의 한계
- 로컬 개발 환경 : API 라우트는 로컬 개발 환경에서 Next.js 서버와 함께 동작한다. 서버리스 함수로 배포 시, 환경에 따라 함수 실행 시간이 제한될 수 있다.
- 서버리스 환경 : API 라우트는 기본적으로 서버리스 함수로 동작하기 때문에, 함수 실행 시간, 연결 유지 시간, 메모리 제한 등 서버리스 플랫폼의 제약을 받는다.
미들웨어 사용
Next.js API 라우터에서는 미들웨어를 사용하여 요청을 처리하기 전에 공통 작업을 수행할 수 있다. 미들웨어는 요청을 가로채어 처리한 후, 다음 작업으로 넘어가도록 할 수 있다.
//pages/api/with-middleware.js
function logger(req,res,next){
console.log(`${req.method} ${req.url}`);
next();
}
export default function handler(req,res)
logger(req,res, () => {
res.status(200).json({ message : 'Hello with middleware!'});
});
}
- 미들웨어는 `req`, `res` 객체를 받아 추가 작업을 수행하고, `next()`를 호출하여 다음 단계로 넘어간다.
CORS(Cross-Orgin Resource Sharing) 처리
- 웹 애플리케이션에서 보안을 강화하기 위해 필요
- 웹 브라우저에서 다른 출처(도메인, 프로토콜, 포트)의 리소스에 접근할 때 발생하는 문제를 해결하기 위한 보안 기능
- Next.js API 라우트는 기본적으로 동일 출처 정책(Same-Orign Policy)을 따른다. 따라서 다른 도메인에서 API 라우트를 호출하려면 CORS 헤더를 설정해야 한다.
export default function handler(req, res){
res.setHeader('Access-Control-Allow-Origin', '*'); //모든 도메인에서 접근 허용
res.status(200).json({ message : 'CORS enabled!'});
}
CORS 필요한 이유
보안강화 : 동일 출처 정책은 웹 애플리케이션이 악의적인 사이트로부터 데이터를 무단으로 가져오거나, 사용자 정보를 탈취하는 등의 보안 문제를 방지한다. 이 정책이 없으면, 사용자가 로그인한 사이트와 관련 없는 사이트가 사용자의 민감한 정보를 가져오는 등의 공격에 노출될 수 있다.
CORS 처리의 필요성
API 호출 : 웹 애프리케이션이 다른 도메인에 있는 API 서버로 데이터를 요청하는 경우
CDN 사용 : 웹 애플리케이션에서 다른 도메인에 위치한 CDN(Content Delivery Network)에서 리소스(이미지,CSS파일)를 로드하는 경우
타사 서비스 연동 : 페이먼트 게이트웨이, 소셜 미디어 로그인 등의 외부 서비스를 통합하는 경우
`Access-Control-Allow-Origin` | 특정 출처 또는 모든 출처(`*`)에서 리소스에 접근할 수 있음을 명시 |
`Access-Control-Allow-Methods` | 허용되는 HTTP 메서드(get, post, put, delete)를 지정 |
`Access-Control-Allow-Headers` | 클라이언트에서 사용할 수 있는 커스텀 헤더를 명시 |
`Access-Control-Allow-Credentials` | 클라이언트 요청이 쿠키를 포함할 수 있도록 허용 |
app.user((req, res, next) => {
//모든 출처에 접근 허용
req.setHeader('Access-Control-Allow-Origin','*');
//허용할 메서드
req.setHeader('Access-Control-Allow-Methods','GET, POST, PUT, DELETE');
//허용할 헤더
req.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
next();
});
- 이 설정을 통해 클라이언트는 다른 출처에서 API 요청을 보낼 수 있으며, 서버는 이를 허용한다.
보안
- 웹 보안을 유지하면서도 필요한 경우 다른 출처와 상호작용할 수 있는 유연성을 제공한다.
- 하지만, CORS 설정을 부적절하게 사용하면 오히려 보안에 취약해질 수 있다. `Access-Control-Allow-Origin: *`은 모든 출처에 접근을 허용하므로, 민감한 데이터를 처리하는 API에서는 사용하지 않는 것이 좋다.
'Frontend > Next.js' 카테고리의 다른 글
[Next.js] Next-Auth (Google) (0) | 2024.08.20 |
---|---|
[Next.js] css 모듈 사용 / 데이터 패칭 (geStaticProps, getServerSideProps) (0) | 2024.08.20 |
[Next.js] 라우팅 / getStaticPaths & getStaticProps / userRouter Hook / Redirects & Rewrites (0) | 2024.08.19 |
[Next.js] next.js 시작하기 ( next.js란? / 장점 / 동작과정 / 프로젝트 생성 ) (0) | 2024.08.10 |