Next.js는 자체 서버를 제공하기 때문에 별도의 서버를 준비하고 실행할 필요가 없음.
하지만 Next.js는 커스텀 웹 서버에서도 웹 애플리케이션을 쉽게 실행할 수 있도록 직관적인 API를 제공.
정말 커스텀 서버가 필요할까?
패키지 설치
$ yarn add express react react-dom next
페이지 루트에다가 index.js 파일 생성
const { parse } = require("url");
const express = require("express");
const next = require("next");
async function main() {
try {
await app.prepare();
const handle = app.getRequestHandler();
const server = express();
server
.get("*", (req, res) => {
const url = parse(req.url, true);
handle(req, res, url);
})
.listen(3000, () => console.log("server ready"));
} catch (err) {
console.log(err.stack);
}
}
main();
페이지 생성을 위해 pages디렉토리 생성 후 파일 생성
export default function Hompage() {
return <div>Homepage</div>;
}
yarn next
명령어를 입력하고 http://localhost:3000/ 으로 접속하면 Homepage가 나타난다.
동적 라우트도 동작한다.
Next.js에 express같은 커스텀 서버를 추가해서 API 서버를 만드는게 가능하지만
간단하게 Next.js에 API를 추가해서 vercel로 배포할 수도 있다.
Next.js API Route는 간단하게 API를 추가할 수 있다. 이 기능은 pages/api 디렉토리 안에 만들어진 파일들이 Rest API path가 된다.
create-next-app
을 통해서 만든 Next.js 프로젝트에는 기본적으로 pages/api/hello.ts
파일이 있는데, 해당 경로로 API를 보내면 파일에 있는 response를 반환한다.
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
type Data = {
name: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
res.status(200).json({ name: 'John Doe' })
}
직접 API를 추가해보자.
api 디렉토리에 pokemon.ts 파일을 만들고 아래 코드를 작성한다.
import type { NextApiRequest, NextApiResponse } from "next";
type PokemonData = {
pokemon: {
name: string;
};
};
export default function handler(
req: NextApiRequest,
res: NextApiResponse<PokemonData>
) {
res.status(200).json({
pokemon: {
name: "꼬부기",
},
});
}
만약 api/pokemon/[id] 로 요청이 왔을때 응답을 하려면
/pages/api/pokemon/[id].ts
로 파일을 만들어서 아래 코드를 작성.
import type { NextApiRequest, NextApiResponse } from "next";
export type Pokemon = {
id: number;
name: string;
};
type PokemonListData = {
pokemonList: Pokemon[];
};
export const pokemonList = [
{
id: 1,
name: "꼬부기",
},
{
id: 2,
name: "파이리",
},
{
id: 3,
name: "이상해씨",
},
];
export default function handler(
req: NextApiRequest,
res: NextApiResponse<PokemonListData>
) {
res.status(200).json({
pokemonList,
});
}
import { NextApiRequest, NextApiResponse } from "next";
import { Pokemon, pokemonList } from ".";
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Pokemon>
) {
const { id } = req.query;
const pokemon = pokemonList.filter(
(pokemon) => (id as string) === pokemon.id.toString()
)[0];
res.status(200).json({
id: pokemon.id,
name: pokemon.name,
});
}
이외에도 DB와 연동해서 직접 데이터베이스와 데이터를 주고받을 수 있다.