Romaji to Kana Converter: React & Next.js — Chapter 1, Exercise 2 ===================================================================== TASK Add a second placeholder route, POST /api/echo, that reads a JSON body of the shape {"message": "..."} and returns it back unchanged. Confirm it with a real POST request, and explain why this route needs request.json() where /api/ping needed nothing from the request at all. SOLUTION // src/app/api/echo/route.ts export async function POST(request: Request) { const body = await request.json(); return Response.json(body); } Verified with a real POST request: $ curl -X POST http://localhost:3000/api/echo \ -H "Content-Type: application/json" \ -d '{"message":"hello"}' {"message":"hello"} The response body matches the request body exactly, confirming the route correctly reads and echoes back real JSON data. The reason /api/echo needs request.json() while /api/ping needed nothing from the request at all comes down to what each route actually has to do with the incoming HTTP request. /api/ping's own GET handler produces a fixed, hardcoded response regardless of anything the client sends -- there's no request body on a GET request in the first place, and even the URL itself carries no information the handler cares about. /api/echo's whole job, by contrast, is to read data the client sent and hand it back, so it genuinely needs to parse the real request body before it has anything to return. request.json() is the real Web Request API method for that -- it reads the raw request stream and parses it as JSON, matching exactly how Chapter 4's own POST /api/convert route will later read the { "romaji": "..." } payload the UI sends it. WHY THIS WORKS AS AN ANSWER ---------------------------- It builds a real, tested second route (not just described in the abstract) and grounds the GET-vs-POST distinction in what each handler's own real job requires from the request, rather than stating "POST needs a body" as an isolated rule with no connection to why.