Skip to Content
Course content

95: Vapor Routing Basics

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Routing is really the heart of any web API. In Vapor, it's how we tell the server: "When a request comes in at this specific URL using this specific HTTP method, run this specific piece of Swift code." It's essentially a giant switch statement for the internet.

To get a feel for this, let's build a tiny API for a personal book collection. We aren't worrying about a database yet; we'll just use a hardcoded array of strings to keep things moving.

Creating the main catalog list

I always start with the simplest "GET" request. I want a route where, if I visit /books, I get a list of everything I own. In Vapor, we use the app instance to define these routes.

app.get("books") { req -> String in
    let myBooks = ["The Hobbit", "Neuromancer", "Foundation"]
    return myBooks.joined(separator: ", ")
}

Notice that I'm returning a String. Vapor is smart enough to know that if you return a string, it should wrap that in an HTTP 200 OK response with a text/plain content type. It's a very clean way to handle simple responses.

Fetching a specific book by ID

Now, returning a whole list is fine, but usually, we want a specific item. This is where dynamic routing comes in. We use a colon (:) to tell Vapor that a segment of the URL is actually a variable parameter, not a literal string.

app.get("books", ":bookID") { req -> String in
    let bookID = req.parameters.get("bookID") ?? "unknown"
    return "You are looking for book number \(bookID)"
}

By adding :bookID, any request to /books/1 or /books/42 will hit this handler. I'm using req.parameters.get to pull that value out of the URL.

Fixing a parameter mismatch

Here is where I usually trip up when I'm moving quickly. I once spent ten minutes wondering why my route was returning "unknown" every single time, even though the URL looked perfect. I'd written this:

// The Mistake
app.get("books", ":bookID") { req in
    let id = req.parameters.get("id") // I called it "id" here...
    return "Book \(id ?? "unknown")"
}

The problem? The string I used in req.parameters.get("id") didn't match the name I gave the parameter in the route definition (:bookID). Vapor doesn't know they are the same thing; it's looking for a key named "id" that doesn't exist in the request parameters. I had to go back and make sure both were exactly "bookID". Always double-check those strings.

Handling a "New Arrival" with POST

GET is for reading, but if we want to add a book to our collection, we need a POST route. This is structurally very similar to our GET routes, but it signals to the client that we are creating something new on the server.

app.post("books") { req -> String in
    // In a real app, we'd decode a JSON body here.
    // For now, we'll just simulate a success.
    return "Book added to the collection!"
}

Now we have a basic set of routes: one to list books, one to find a specific one, and one to add a new one. That's the foundation of almost every REST API you'll ever encounter.




📋 Practical Task

Building a Book Category Filter

Your task is to expand the book API. Create a new GET route that allows a user to filter books by category. The URL should follow the pattern /books/category/:categoryName (for example, /books/category/sci-fi).

The route should:

  • Capture the categoryName parameter from the URL.
  • Return a string that says: "Listing all books in the [categoryName] category."
  • Ensure the parameter name used in req.parameters.get() matches the one defined in the route path exactly.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.