Server Routes
In Next.js, an API route is a file called route.ts that exports named functions: GET, POST, PUT, DELETE. The HTTP method is the function name. The file lives inside app/api/, right next to your pages.
Nuxt encodes the HTTP method in the filename: index.get.ts handles GET requests, while index.post.ts handles POST. Server code lives in server/api/, separate from the Vue app. Nitro compiles those routes into the server output used by platforms such as Vercel.
You'll expose the 17 hot springs in the JSON file through an API route.
Outcome
Create a server route that returns all hot springs from the JSON data file.
Fast Track
- Create
server/api/springs/index.get.tswith a basic event handler - Import and return the springs JSON data
- Test the endpoint at
/api/springsin the browser
Hands-on exercise 2.1
Build the first server route for the app: a GET endpoint that returns all hot springs.
Requirements:
- Create
server/api/springs/index.get.ts - Import the springs data from
server/data/springs.json - Return the full array of springs
- Verify the endpoint returns JSON at
/api/springs
Implementation hints:
defineEventHandleris the Nuxt equivalent of exporting aGETfunction in Next.js. It's auto-imported in theserver/directory- You can import JSON files directly with
import springs from "~/server/data/springs.json" - The
~/alias resolves to the project root in server code, just like in app code - Return a value and Nitro automatically serializes it as JSON with the correct content type
In Next.js, a basic API route looks like this:
// app/api/springs/route.ts: Next.js version
import { NextResponse } from "next/server";
import springs from "@/data/springs.json";
export async function GET() {
return NextResponse.json(springs);
}Here's the Nuxt version:
import type { Spring } from "~/types/spring";
import springs from "~/server/data/springs.json";
export default defineEventHandler((event) => {
return springs as Spring[];
});Return a value and Nitro serializes it, so this handler does not need a NextResponse.json() wrapper. The event parameter provides access to the request, query parameters, headers, and body when a route needs them.
The filename does real work here. index.get.ts tells Nitro three things: this handles requests to the root of the /api/springs path (index), it only responds to GET requests (.get), and it's a TypeScript file (.ts). If someone sends a POST to this endpoint, Nitro returns a 405 automatically.
Next.js can export several methods from one route.ts file. Nuxt uses one file per method, so the filename identifies the route's HTTP method.
Try It
Start the dev server and visit http://localhost:3000/api/springs in your browser. You should see a JSON array of 17 hot springs:
[
{
"id": "breitenbush-hot-springs",
"name": "Breitenbush Hot Springs",
"description": "Tucked into the Willamette National Forest...",
"location": {
"region": "Pacific Northwest",
"country": "US",
"lat": 44.7896,
"lng": -121.9815
},
"temperature": { "min": 98, "max": 112 },
"type": "developed",
"features": ["clothing-optional", "forest-setting", ...],
"elevation": 2200,
"imageUrl": "/images/springs/breitenbush-hot-springs.jpg"
},
...
]You can also test with curl:
curl http://localhost:3000/api/springs | head -c 200If you see the JSON data, the route is working. If you get a 404, make sure the file is at server/api/springs/index.get.ts, not app/api/springs/index.get.ts. The server directory is a common source of misplaced files when you're coming from Next.js.
Commit
git add -A && git commit -m "feat(api): add GET /api/springs server route"Done-When
server/api/springs/index.get.tsexists and exports a default event handler- Visiting
/api/springsreturns a JSON array of 17 hot springs - You can explain how filename conventions (
.get.ts,.post.ts) replace exported function names in Next.js
Solution
import type { Spring } from "~/types/spring";
import springs from "~/server/data/springs.json";
export default defineEventHandler((event) => {
return springs as Spring[];
});Was this helpful?