HTTP and SQLite

Route requests and return JSON

Use Bun.serve routes to match HTTP methods and paths, read path parameters, and return useful JSON responses.

9 minute lesson

~~~

Bun can match routes before calling the fallback fetch handler.

Let’s create two read-only routes:

type Note = {
  id: number
  title: string
}

const notes: Note[] = [
  { id: 1, title: 'Learn Bun' },
  { id: 2, title: 'Build the notes API' },
]

const server = Bun.serve({
  routes: {
    '/api/notes': {
      GET: () => Response.json(notes),
    },
    '/api/notes/:id': request => {
      const id = Number(request.params.id)
      const note = notes.find(note => note.id === id)

      if (!note) {
        return Response.json(
          { error: 'Note not found' },
          { status: 404 },
        )
      }

      return Response.json(note)
    },
  },
  fetch() {
    return Response.json(
      { error: 'Route not found' },
      { status: 404 },
    )
  },
})

console.log(`Listening on ${server.url}`)

The :id segment creates request.params.id. It is a string, so we convert it before comparing it with numeric IDs.

Try the collection route:

curl http://localhost:3000/api/notes

Then request one note:

curl http://localhost:3000/api/notes/1

An unknown ID returns JSON with status 404. An unmatched path reaches fetch() and returns a different 404 response.

HTTP status codes are part of the API contract. Do not return 200 for every outcome and ask clients to inspect an error string.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →