Bird
Raised Fist0
NextJSframework~10 mins

Route handlers (route.ts) in NextJS - Interactive Code Practice

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to export a GET route handler that returns a JSON response.

NextJS
export async function GET(req: Request) {
  return new Response(JSON.stringify({ message: [1] }), {
    headers: { 'Content-Type': 'application/json' },
  });
}
Drag options to blanks, or click blank then click option'
A"Hello from GET"
BHello from GET
C'Hello from GET'
DGET
Attempts:
3 left
💡 Hint
Common Mistakes
Forgetting quotes around the string value inside JSON.stringify.
Returning a plain string instead of a JSON string.
2fill in blank
medium

Complete the code to parse JSON from the POST request body.

NextJS
export async function POST(req: Request) {
  const data = await req.[1]();
  return new Response(JSON.stringify({ received: data }), {
    headers: { 'Content-Type': 'application/json' },
  });
}
Drag options to blanks, or click blank then click option'
Ajson
BformData
Ctext
DarrayBuffer
Attempts:
3 left
💡 Hint
Common Mistakes
Using req.text() and then manually parsing JSON.
Using req.formData() which is for form submissions.
3fill in blank
hard

Fix the error in the route handler by correctly setting the status code in the Response constructor.

NextJS
export async function DELETE(req: Request) {
  return new Response(null, { status: [1] });
}
Drag options to blanks, or click blank then click option'
A200
B204
C404
D500
Attempts:
3 left
💡 Hint
Common Mistakes
Using 200 status code but returning null body.
Using error codes like 404 or 500 for successful deletes.
4fill in blank
hard

Fill both blanks to create a route handler that reads a query parameter 'id' from the URL and returns it in JSON.

NextJS
export async function GET(req: Request) {
  const url = new URL(req.url);
  const id = url.[1].get('[2]');
  return new Response(JSON.stringify({ id }), {
    headers: { 'Content-Type': 'application/json' },
  });
}
Drag options to blanks, or click blank then click option'
AsearchParams
Bid
Cquery
DqueryParams
Attempts:
3 left
💡 Hint
Common Mistakes
Using url.params instead of url.searchParams.
Using wrong parameter name.
5fill in blank
hard

Fill all three blanks to create a POST route handler that reads JSON body, extracts 'name', and returns a greeting message.

NextJS
export async function POST(req: Request) {
  const data = await req.[1]();
  const name = data.[2] ?? 'Guest';
  return new Response(JSON.stringify({ message: `Hello, [3]!` }), {
    headers: { 'Content-Type': 'application/json' },
  });
}
Drag options to blanks, or click blank then click option'
Ajson
Bname
C${name}
Dtext
Attempts:
3 left
💡 Hint
Common Mistakes
Using req.text() instead of req.json().
Accessing data['name'] incorrectly.
Not using template literals for string interpolation.

Practice

(1/5)
1. What is the main purpose of a route.ts file in Next.js?
easy
A. To configure database connections
B. To style components using CSS modules
C. To create client-side React components
D. To define server-side code that handles HTTP requests for a specific URL

Solution

  1. Step 1: Understand the role of route.ts

    The route.ts file is used in Next.js to write server-side code that responds to HTTP requests for a specific route.
  2. Step 2: Compare with other options

    Styling, client components, and database configs are handled elsewhere, not in route.ts.
  3. Final Answer:

    To define server-side code that handles HTTP requests for a specific URL -> Option D
  4. Quick Check:

    Route handlers = server code for URLs [OK]
Hint: Route handlers handle server requests per URL [OK]
Common Mistakes:
  • Confusing route.ts with client component files
  • Thinking route.ts is for styling
  • Assuming route.ts manages database directly
2. Which of the following is the correct way to export a GET handler in route.ts?
easy
A. export async function GET(request: NextRequest) { return NextResponse.json({ message: 'Hi' }) }
B. export function Get() { return 'Hello' }
C. export async function get() { return new Response('Hello') }
D. export async function fetch() { return 'Hello' }

Solution

  1. Step 1: Recall Next.js route handler syntax

    Next.js expects exported async functions named exactly by HTTP method in uppercase, e.g., GET, with NextRequest parameter and returning NextResponse.
  2. Step 2: Check each option

    export async function GET(request: NextRequest) { return NextResponse.json({ message: 'Hi' }) } matches correct syntax: async, uppercase GET, parameter, and returns NextResponse. Others have wrong function names, casing, or return types.
  3. Final Answer:

    export async function GET(request: NextRequest) { return NextResponse.json({ message: 'Hi' }) } -> Option A
  4. Quick Check:

    Uppercase method + NextRequest + NextResponse = correct [OK]
Hint: Use uppercase HTTP method and NextRequest param [OK]
Common Mistakes:
  • Using lowercase method names like get instead of GET
  • Missing NextRequest parameter
  • Returning plain string instead of NextResponse
3. Given this route.ts code, what will be the JSON response body when a GET request is made?
import { NextResponse } from 'next/server';

export async function GET() {
  return NextResponse.json({ success: true, data: [1, 2, 3] });
}
medium
A. undefined
B. {"success":true,"data":[1,2,3]}
C. {"error":"Method not allowed"}
D. [1, 2, 3]

Solution

  1. Step 1: Analyze the GET handler return

    The GET function returns NextResponse.json with an object containing success: true and data: [1, 2, 3].
  2. Step 2: Understand JSON response format

    This creates a JSON response with the exact object serialized as a JSON string.
  3. Final Answer:

    {"success":true,"data":[1,2,3]} -> Option B
  4. Quick Check:

    NextResponse.json outputs JSON string [OK]
Hint: NextResponse.json sends exact JSON object [OK]
Common Mistakes:
  • Expecting just the array without wrapping object
  • Confusing error responses with success
  • Thinking response is undefined
4. Identify the error in this route.ts code snippet:
export async function POST(request: NextRequest) {
  const data = await request.json();
  return new Response(JSON.stringify(data));
}

export async function GET() {
  return new Response('Hello');
}
medium
A. Missing import of NextRequest
B. GET function must accept a request parameter
C. POST handler should return NextResponse, not Response
D. No error, code is correct

Solution

  1. Step 1: Check imports

    The code uses NextRequest but does not import it from 'next/server'. This causes a runtime error.
  2. Step 2: Validate other parts

    GET handler can omit request parameter if unused. Returning Response is allowed but NextResponse is preferred; not an error. So main error is missing import.
  3. Final Answer:

    Missing import of NextRequest -> Option A
  4. Quick Check:

    Using NextRequest requires import [OK]
Hint: Always import NextRequest when used [OK]
Common Mistakes:
  • Forgetting to import NextRequest
  • Thinking GET must have request param
  • Confusing Response and NextResponse as errors
5. You want to create a route handler in route.ts that responds to both GET and POST requests. The GET returns a JSON list of users, and the POST adds a user from the request body and returns the updated list. Which code snippet correctly implements this behavior?
hard
A. export async function GET(request) { return new Response(JSON.stringify(['Alice', 'Bob'])); } export async function POST(request) { const data = await request.json(); return new Response(JSON.stringify(['Alice', 'Bob'])); }
B. import { NextRequest } from 'next/server'; const users = []; export function get() { return users; } export function post(request) { users.push(request.body.name); return users; }
C. import { NextRequest, NextResponse } from 'next/server'; let users = ['Alice', 'Bob']; export async function GET() { return NextResponse.json(users); } export async function POST(request: NextRequest) { const newUser = await request.json(); users.push(newUser.name); return NextResponse.json(users); }
D. import { NextResponse } from 'next/server'; export async function GET() { return NextResponse.json(['Alice', 'Bob']); } export async function POST() { return NextResponse.json(['Alice', 'Bob', 'Charlie']); }

Solution

  1. Step 1: Check imports and state management

    import { NextRequest, NextResponse } from 'next/server'; let users = ['Alice', 'Bob']; export async function GET() { return NextResponse.json(users); } export async function POST(request: NextRequest) { const newUser = await request.json(); users.push(newUser.name); return NextResponse.json(users); } correctly imports NextRequest and NextResponse, and uses a mutable users array to store state between calls.
  2. Step 2: Verify GET and POST handlers

    GET returns current users as JSON. POST reads JSON body, adds new user, then returns updated list. This matches requirements.
  3. Step 3: Review other options

    import { NextRequest } from 'next/server'; const users = []; export function get() { return users; } export function post(request) { users.push(request.body.name); return users; } uses lowercase method names and no NextResponse, invalid in Next.js route handlers. export async function GET(request) { return new Response(JSON.stringify(['Alice', 'Bob'])); } export async function POST(request) { const data = await request.json(); return new Response(JSON.stringify(['Alice', 'Bob'])); } returns new Response but does not maintain state. import { NextResponse } from 'next/server'; export async function GET() { return NextResponse.json(['Alice', 'Bob']); } export async function POST() { return NextResponse.json(['Alice', 'Bob', 'Charlie']); } POST does not accept request or update users dynamically.
  4. Final Answer:

    import { NextRequest, NextResponse } from 'next/server'; let users = ['Alice', 'Bob']; export async function GET() { return NextResponse.json(users); } export async function POST(request: NextRequest) { const newUser = await request.json(); users.push(newUser.name); return NextResponse.json(users); } -> Option C
  5. Quick Check:

    Correct imports + state + async handlers = import { NextRequest, NextResponse } from 'next/server'; let users = ['Alice', 'Bob']; export async function GET() { return NextResponse.json(users); } export async function POST(request: NextRequest) { const newUser = await request.json(); users.push(newUser.name); return NextResponse.json(users); } [OK]
Hint: Use async GET/POST with NextRequest, NextResponse, and shared state [OK]
Common Mistakes:
  • Using lowercase method names instead of uppercase
  • Not importing NextRequest or NextResponse
  • Not maintaining state between requests
  • Ignoring async/await for request.json()