Урок 02

Обработка запросов

Чтение тела

export async function POST(request: Request) {
    const body = await request.json();       // JSON
    const text = await request.text();       // текст
    const form = await request.formData();   // FormData
    const blob = await request.blob();       // бинарные
}

Тело можно прочитать только один раз.

JSON

export async function POST(request: Request) {
    const { title, body } = await request.json();

    const post = await db.post.create({ data: { title, body } });
    return Response.json(post, { status: 201 });
}

FormData

export async function POST(request: Request) {
    const formData = await request.formData();

    const title = formData.get('title') as string;
    const file = formData.get('file') as File;

    return Response.json({ title, filename: file.name });
}

Query-параметры

export async function GET(request: Request) {
    const { searchParams } = new URL(request.url);

    const page = Number(searchParams.get('page') ?? 1);
    const limit = Number(searchParams.get('limit') ?? 10);
    const tags = searchParams.getAll('tag');

    return Response.json({ page, limit, tags });
}

Заголовки

export async function GET(request: Request) {
    const auth = request.headers.get('authorization');
    const contentType = request.headers.get('content-type');
    const accept = request.headers.get('accept');

    return Response.json({ auth, contentType });
}

Cookies

import { cookies } from 'next/headers';

export async function GET() {
    const cookieStore = await cookies();
    const token = cookieStore.get('token')?.value;

    return Response.json({ hasToken: !!token });
}

Установка:

export async function POST() {
    const cookieStore = await cookies();

    cookieStore.set('token', 'value', {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'lax',
        maxAge: 60 * 60 * 24 * 7,
    });

    return Response.json({ ok: true });
}

Или через ответ:

const response = Response.json({ ok: true });
response.headers.set(
    'Set-Cookie',
    'token=value; HttpOnly; Secure; SameSite=Lax; Max-Age=604800'
);
return response;

Метод

export async function GET(request: Request) {
    console.log(request.method); // 'GET'
    return Response.json({ method: request.method });
}

URL

export async function GET(request: Request) {
    const url = new URL(request.url);
    console.log(url.pathname);
    console.log(url.search);
    console.log(url.searchParams.get('page'));

    return Response.json({ ok: true });
}

IP и геолокация

export async function GET(request: Request) {
    const ip = request.headers.get('x-forwarded-for') ?? 'unknown';
    const country = request.headers.get('x-vercel-ip-country');
    const city = request.headers.get('x-vercel-ip-city');

    return Response.json({ ip, country, city });
}

Доступно на Vercel и некоторых хостингах.

User Agent

const ua = request.headers.get('user-agent');

Итоги

  • await request.json() для JSON
  • formData() для форм
  • searchParams из URL
  • headers.get() для заголовков
  • cookies() для кук
  • x-forwarded-for для IP