HTTP 메서드 처리
Next.js API 라우트에서 다양한 HTTP 메서드를 처리하는 방법을 알아보겠습니다.
각 메서드별 처리 로직, 요청 검증, 그리고 적절한 응답 구조화에 중점을 두고 설명하겠습니다.
HTTP 메서드별 처리 로직
Next.js에서는 각 HTTP 메서드에 대해 별도의 함수를 export하여 처리할 수 있습니다.
export async function GET(request) {
// GET 요청 처리 로직
}
export async function POST(request) {
// POST 요청 처리 로직
}
export async function PUT(request) {
// PUT 요청 처리 로직
}
export async function DELETE(request) {
// DELETE 요청 처리 로직
}
요청 본문 및 쿼리 파라미터 처리
POST 및 PUT 요청의 본문 처리
export async function POST(request) {
const body = await request.json()
// body를 사용한 로직
}
쿼리 파라미터 처리
export async function GET(request) {
const { searchParams } = new URL(request.url)
const query = searchParams.get('query')
// query를 사용한 로직
}
상태 코드와 응답 반환
적절한 HTTP 상태 코드와 함께 응답을 반환하는 것이 중요합니다.
export async function POST(request) {
try {
const body = await request.json()
// 데이터 처리 로직
return new Response(JSON.stringify({ message: 'Created successfully' }), {
status: 201,
headers: { 'Content-Type': 'application/json' }
})
} catch (error) {
return new Response(JSON.stringify({ error: 'Invalid request' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
})
}
}
요청 검증
요청을 처리하기 전에 유효성을 검사하는 것이 중요합니다.
export async function PUT(request) {
const body = await request.json()
if (!body.id || !body.name) {
return new Response(JSON.stringify({ error: 'Missing required fields' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
})
}
// 유효한 요청 처리 로직
}
8장 폼 제출 및 데이터 처리와의 연관성
11장의 HTTP 메서드 처리는 8장에서 다룬 폼 제출 및 데이터 처리와 밀접하게 연관됩니다.
클라이언트에서 폼을 제출할 때, 해당 데이터는 일반적으로 POST 또는 PUT 요청으로 API 라우트에 전송됩니다.
API 라우트에서는 이 데이터를 받아 처리하고, 적절한 응답을 반환합니다.
예를 들어, 8장에서 구현한 폼 제출 로직이 다음과 같다면
const handleSubmit = async (event) => {
event.preventDefault()
const formData = new FormData(event.target)
const response = await fetch('/api/users', {
method: 'POST',
body: JSON.stringify(Object.fromEntries(formData)),
headers: {
'Content-Type': 'application/json',
},
})
const data = await response.json()
// 응답 처리
}
API 라우트에서는 이 요청을 다음과 같이 처리할 수 있습니다.
export async function POST(request) {
const body = await request.json()
// 데이터베이스에 사용자 추가 로직
return new Response(JSON.stringify({ message: 'User created successfully' }), {
status: 201,
headers: { 'Content-Type': 'application/json' }
})
}
실습 : 완전한 CRUD API 구현
사용자 정보를 관리하는 완전한 CRUD(Create, Read, Update, Delete) API를 구현해보겠습니다.
let users = [
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Doe', email: '[email protected]' },
]
export async function GET(request) {
const { searchParams } = new URL(request.url)
const id = searchParams.get('id')
if (id) {
const user = users.find(u => u.id === parseInt(id))
if (user) {
return new Response(JSON.stringify(user), {
status: 200,
headers: { 'Content-Type': 'application/json' }
})
} else {
return new Response(JSON.stringify({ error: 'User not found' }), {
status: 404,
headers: { 'Content-Type': 'application/json' }
})
}
}
return new Response(JSON.stringify(users), {
status: 200,
headers: { 'Content-Type': 'application/json' }
})
}
export async function POST(request) {
const body = await request.json()
if (!body.name || !body.email) {
return new Response(JSON.stringify({ error: 'Name and email are required' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
})
}
const newUser = {
id: users.length + 1,
name: body.name,
email: body.email
}
users.push(newUser)
return new Response(JSON.stringify(newUser), {
status: 201,
headers: { 'Content-Type': 'application/json' }
})
}
export async function PUT(request) {
const body = await request.json()
if (!body.id || !body.name || !body.email) {
return new Response(JSON.stringify({ error: 'Id, name, and email are required' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
})
}
const index = users.findIndex(u => u.id === body.id)
if (index === -1) {
return new Response(JSON.stringify({ error: 'User not found' }), {
status: 404,
headers: { 'Content-Type': 'application/json' }
})
}
users[index] = { ...users[index], ...body }
return new Response(JSON.stringify(users[index]), {
status: 200,
headers: { 'Content-Type': 'application/json' }
})
}
export async function DELETE(request) {
const { searchParams } = new URL(request.url)
const id = searchParams.get('id')
if (!id) {
return new Response(JSON.stringify({ error: 'Id is required' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
})
}
const index = users.findIndex(u => u.id === parseInt(id))
if (index === -1) {
return new Response(JSON.stringify({ error: 'User not found' }), {
status: 404,
headers: { 'Content-Type': 'application/json' }
})
}
const deletedUser = users.splice(index, 1)[0]
return new Response(JSON.stringify(deletedUser), {
status: 200,
headers: { 'Content-Type': 'application/json' }
})
}
이 실습에서는 메모리 내 배열을 사용하여 사용자 데이터를 관리합니다.
실제 애플리케이션에서는 데이터베이스를 사용해야 합니다.
각 HTTP 메서드에 대해 적절한 처리 로직을 구현하고, 요청 검증과 에러 처리를 포함하고 있습니다.
이러한 API 라우트 구현을 통해 클라이언트 측 애플리케이션에서 사용자 데이터를 효과적으로 관리할 수 있습니다.
Next.js의 API 라우트 기능을 활용하면 서버리스 함수로 동작하는 강력한 백엔드 API를 쉽게 구축할 수 있습니다.