Route Handlers[Next.js]

SnowCat·2023년 4월 17일
0

Next.js

목록 보기
6/16
post-thumbnail

  • Rest api 사용을 위한 메서드 작성을 위해 route handlers를 작성할 수 있음

Convention

  • app 폴더 내부에 route.js(ts) 파일을 작성
  • app 디렉토리에 중첩된 경로에도 사용 가능하지만, page.js가 있는 폴더에 route.js를 동시 작성은 불가능함에 주의
  • HTTP 메서드로는 GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS 메서드를 지원하며, 지원하지 않는 메서드를 호출한 경우 405 코드를 반환함

Behavior

  • GET 메서드를 사용할시에는 기본적으로 Route Handler가 정적인 값으로 가정해 서버에 캐시를 저장하게 됨
import { NextResponse } from 'next/server';

export async function GET() {
  const res = await fetch('https://data.mongodb-api.com/...', {
    headers: {
      'Content-Type': 'application/json',
      'API-Key': process.env.DATA_API_KEY,
    },
  });
  const data = await res.json();

  return NextResponse.json({ data }) // Response.json() 사용시 타입스크립트 에러 발생
}
  • 나머지 메서드를 사용할 때나 쿠키, 헤더와 같은 Dynamic function 사용, GET 메서드에 Request 객체를 사용할 시에는 동적 데이터 패칭으로 간주해 요청시마다 데이터를 가져오게 됨
import { NextResponse } from 'next/server';

export async function POST() {
  const res = await fetch('https://data.mongodb-api.com/...', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'API-Key': process.env.DATA_API_KEY,
    },
    body: JSON.stringify({ time: new Date().toISOString() }),
  });

  const data = await res.json();

  return NextResponse.json(data);
}

Example

  • 일정한 시간마다 정적 데이터를 최신화 해줄 수 있음
import { NextResponse } from 'next/server';

export async function GET() {
  const res = await fetch('https://data.mongodb-api.com/...', {
    next: { revalidate: 60 } // Revalidate every 60 seconds
  });
  const data = await res.json();

  return NextResponse.json(data)
}
  • next/headers 에서 쿠키를 가져오는 메서드를 호출할수도 있음
    쿠키는 읽기전용이며, 쿠키를 설정하기 위해서는 Set-Cookie헤더를 Response 객체로 반환해주어야 함
import { cookies } from 'next/headers'

export async function GET(request: Request) {
  const cookieStore = cookies();
  const token = cookieStore.get('token');

  return new Response('Hello, Next.js!', {
    status: 200,
    headers: { 'Set-Cookie': `token=${token}` }
  });
}

// NextRequest를 사용해도 쿠키를 가져올 수 있음
import { type NextRequest } from 'next/server'

export async function GET(request: NextRequest) {
  const token = request.cookies.get('token')
}
  • next/headers 에서 headers를 가져오면 request header를 가져올 수 있으며, 쿠키와 마찬가지로 read-only 속성이기 때문에 set을 위해서는 새로운 Response 객체에 헤더를 반환해야 함
import { headers } from 'next/headers';

export async function GET(request: Request) {
  const headersList = headers();
  const referer = headersList.get('referer');

  return new Response('Hello, Next.js!', {
    status: 200,
    headers: { 'referer': referer }
  });
}

// NextRequest를 사용하는 방법
import { type NextRequest } from 'next/server'

export async function GET(request: NextRequest) {
  const requestHeaders = new Headers(request.headers)
}
  • request body의 경우는 자바스크립트 api를 사용
import { NextResponse } from 'next/server';

export async function POST(request: Request) {
  const res = await request.json();
  return NextResponse.json({ res })
}
  • redirrect 메서드를 사용해 메서드 사용시 리다이렉트를 시켜줄 수 있음
import { redirect } from 'next/navigation';

export async function GET(request: Request) {
  redirect('https://nextjs.org/')
}
  • dynamic segments의 경우 param을 값으로 가져올 수 있음
// ex: app/[id]/route.js
export async function GET(request: Request, { params }: {
  params: { id: string }
}) {
  const id = params.id;
}
  • 스트리밍을 위한 인코딩, 디코딩 기능을 지원함
// https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#convert_async_iterator_to_stream
function iteratorToStream(iterator: any) {
  return new ReadableStream({
    async pull(controller) {
      const { value, done } = await iterator.next()

      if (done) {
        controller.close()
      } else {
        controller.enqueue(value)
      }
    },
  })
}

function sleep(time: number) {
  return new Promise((resolve) => {
    setTimeout(resolve, time)
  })
}

const encoder = new TextEncoder()

async function* makeIterator() {
  yield encoder.encode('<p>One</p>')
  await sleep(200)
  yield encoder.encode('<p>Two</p>')
  await sleep(200)
  yield encoder.encode('<p>Three</p>')
}

export async function GET() {
  const iterator = makeIterator()
  const stream = iteratorToStream(iterator)

  return new Response(stream)
}
profile
냐아아아아아아아아앙

0개의 댓글