Skip to main content
In this lesson we add a GET route that returns a single product by its ID as JSON. The following sections present the product model, helper functions to fetch all products and a single product from the database, the HTTP handler, and how to register the routes in your application. Code examples assume a standard Go web app using database/sql and gorilla/mux. Key topics covered:
  • product model and querying all products
  • parameterized single-row query to fetch a product by ID
  • HTTP handler for GET /product/
  • route registration
Useful references:

Product model and getProducts (fetch all)

Define the product struct and a helper function to return all products from the database. This function uses a simple SELECT and scans the rows into a slice of products.
Example response returned by /products (for reference):

Register routes

Register the routes for listing all products and fetching a single product by ID. This assumes your App struct includes Router *mux.Router and DB *sql.DB, and that the handler methods are defined on App.
Table — Routes overview

Fetch a single product (model method)

Create a method on product that populates the struct fields based on the product ID. Always use parameterized queries to avoid SQL injection. The placeholder token depends on your SQL driver (e.g., ? for MySQL, $1 for Postgres). The example below uses ?—adjust for your driver accordingly.
When using database/sql, prefer QueryRow with arguments rather than formatting values into the SQL string. This avoids SQL injection and is safer.

Handler: GET /product/

The handler extracts the {id} path variable using mux.Vars, converts it to an integer with strconv.Atoi, constructs a product{ID: key}, calls the model method, and returns the appropriate HTTP response:
  • 400 Bad Request when the path parameter is missing or not an integer.
  • 404 Not Found when no matching row exists.
  • 500 Internal Server Error for other DB errors.
  • 200 OK with the product JSON on success.
Notes:
  • sendError and sendResponse are utility helpers that should write JSON responses and set the proper Content-Type and status code.
  • The getProduct method uses a pointer receiver so the handler can return the populated product value directly.
Example implementations for utility functions (not required, but typically like):

Example requests and responses

  • GET a valid product:
    • Request: GET http://localhost:10000/product/1
    • Response 200:
  • GET with an invalid integer ID:
    • Request: GET http://localhost:10000/product/abc
    • Response 400:
  • GET a non-existent product ID:
    • Request: GET http://localhost:10000/product/10
    • Response 404:
Summary With the model method, handler, and routes above wired into your application, you will have:
  • /products — returns all products as JSON
  • /product/ — retrieves a single product by ID with proper error handling and secure parameterized queries
For more best practices and production considerations, see:

Watch Video