To build our REST API, we'll utilize the net/http package for handling HTTP requests and the gorilla/mux package for routing. Ensure you have Go installed on your machine and follow along with the steps below.

Step 1: Setting Up Your Go Environment

First, create a new directory for your project and navigate into it:

mkdir go-rest-api
cd go-rest-api

Next, initialize a new Go module:

go mod init go-rest-api

Then, install the gorilla/mux package:

go get -u github.com/gorilla/mux

Step 2: Creating the API Structure

Create a new file named main.go in your project directory. This file will contain the main logic for our API.

package main

import (
    "encoding/json"
    "net/http"
    "github.com/gorilla/mux"
)

// Define a struct to represent a book
type Book struct {
    ID     string  `json:"id,omitempty"`
    Title  string  `json:"title,omitempty"`
    Author string  `json:"author,omitempty"`
}

// Initialize a slice to store books
var books []Book

// Handler to get all books
func GetBooks(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(books)
}

// Handler to create a new book
func CreateBook(w http.ResponseWriter, r *http.Request) {
    var book Book
    _ = json.NewDecoder(r.Body).Decode(&book)
    books = append(books, book)
    w.WriteHeader(http.StatusCreated)
    json.NewEncoder(w).Encode(book)
}

// Main function to set up routes and start the server
func main() {
    router := mux.NewRouter()

    // Define routes
    router.HandleFunc("/books", GetBooks).Methods("GET")
    router.HandleFunc("/books", CreateBook).Methods("POST")

    // Start server
    http.ListenAndServe(":8000", router)
}

Step 3: Running the API

To run your API, execute the following command in your terminal:

go run main.go

Your API will now be running on http://localhost:8000. You can test the endpoints using tools like curl or Postman.

Step 4: Testing the API Endpoints

4.1: Adding a Book

You can add a new book using a POST request. Here’s an example using curl:

curl -X POST -H "Content-Type: application/json" -d '{"id":"1", "title":"The Great Gatsby", "author":"F. Scott Fitzgerald"}' http://localhost:8000/books

4.2: Retrieving All Books

To retrieve all books, use the following GET request:

curl http://localhost:8000/books

You should see a JSON response with the books you added:

[
    {
        "id": "1",
        "title": "The Great Gatsby",
        "author": "F. Scott Fitzgerald"
    }
]

Step 5: Error Handling

In a production-ready API, you should implement error handling. Here’s how you can modify the CreateBook function to handle potential errors:

func CreateBook(w http.ResponseWriter, r *http.Request) {
    var book Book
    if err := json.NewDecoder(r.Body).Decode(&book); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    books = append(books, book)
    w.WriteHeader(http.StatusCreated)
    json.NewEncoder(w).Encode(book)
}

Step 6: Structuring Your API

As your API grows, consider structuring it into multiple files for better maintainability. For example, you could separate your models, routes, and handlers into different packages. Here’s a suggested structure:

go-rest-api/
├── main.go
├── models/
│   └── book.go
├── routes/
│   └── routes.go
└── handlers/
    └── bookHandlers.go

Conclusion

In this tutorial, you learned how to build a simple REST API using Go. We covered setting up your environment, creating routes, handling requests, and returning responses. This foundational knowledge will help you build more complex APIs and services in the future.

Learn more with useful resources