Building REST APIs in Go with Mux and GORM

In modern software development, Application Programming Interfaces (APIs) are essential for building scalable and flexible systems. APIs enable applications to communicate and exchange data, amongst other actions.

Representational State Transfer (REST) is an API specification for building simple, scalable, client-server APIs based on HTTP, stateless, cacheable, and layered.

RESTful APIs provide a medium for interaction between software components, easing the building process of distributed applications. However, building RESTful APIs can be daunting, especially for beginners; that’s where the Gorilla Mux package comes in handy.

The Gorilla Mux package is a powerful HTTP router and dispatcher that simplifies building RESTful APIs. Gorilla Mux allows you to define routes for different HTTP methods (GET, POST, PUT, DELETE, etc.) and handle requests and responses in a structured manner. The Gorilla Mux package is easy to use, and the package supports a range of middleware that you can use for logging and authentication operations, among others.

Getting Started Building Applications in Go

Getting started with building REST APIs with Go is quite easy. First, you must install the latest Go version on your system. The installation process is straightforward. Simply visit the Go downloads webpage to install the Go binary distribution for your computer’s operating system.

Run this command on your terminal to verify that you’ve successfully installed Go.

Once you have installed Go, the next step is creating a new directory and initializing the directory as a Go project.

Run these commands on your terminal to create and initialize a new Go project on your computer.

The go mod command initializes a new Go project in the specified working directory. The command also creates a go.mod file in the directory for managing your project’s dependencies.

Finally, you’ll need some form of persistence for your database. In this tutorial, you’ll learn how to use GORM and a SQL database for persistence for your API. GORM supports a variety of SQL databases, including MSSQL, MySQL, and PostgreSQL. Install your preferred database management system, and you’re good to go.

Building APIs with Gorilla Mux

The Gorilla Mux package is a third-party package, and you’ll need to install the package as one of your project’s dependencies to get started.

Run this command in the terminal of your project’s working directory to install the Gorilla Mux package.

Here’s how to import the Gorilla Mux package into your Go files.

You’ll need to create a new router instance to work with handler functions with the Gorilla Mux package. You can use the NewRouter function to create a new router instance.

After creating a router instance, you can use the HandleFunc function to map handler functions to routes and specify the HTTP method for the routes.

The main function above creates a new router instance and mounts routes to GET, POST, PUT, and DELETE requests before starting a server on port :8080 with the ListenAndServe function of the http package.

Setting Persistence Up GORM for the API

Most of the time, you’ll need persistence when building APIs for data storage and retrieval. GORM is the most popular ORM in the Go ecosystem, and the package is useful for working with many databases.

Run this command to install the GORM package and the SQLite database driver for the package.

You can learn more about GORM from this article if you’re unfamiliar with the package. The article covers the most popular operations with the package while considering other databases.

Here’s the list of imports you’ll need to set up the API, including Gorilla Mux, GORM, and Go built-in packages.

You’ll need a struct model that defines the database schema for queries and data migration. Here’s an example struct for the database schema.

The ID field is the primary key, and the Age and Name fields are regular fields.

You’ll need to access your database instance from multiple handler functions, so you can resort to making it a global variable for accessibility. The DB struct defines a GORM database instance.

You can use a function to manage database auto migrations. You’ll use the Open function of the gorm package to open a database connection from the driver. The sqlite package’s Open function returns a connection instance that GORM can access and return a database instance.

After creating a database instance, you can use the AutoMigrate function of the database instance that takes in the struct model and auto-migrates struct instances.

The DBConnection function is the auto migration function. The function returns an error if there’s any during the migration process.

You can proceed to call the DBConnection function in the main function.

The next step is setting up the handler functions for successful operations.

The POST Request Handler Function

Your POST request handler function would receive a JSON request body from the client, decode the JSON into the Human struct instance and migrate the struct to the database using the Create function of the database instance.

The createHuman handler function creates a handler function instance with HTTP response writer and requests instances as arguments, decodes the JSON to struct with the Decode function of the NewDecoder function, migrates the data to the database, and returns an encoded JSON struct to the client.

Here’s a CURL request that makes a POST request to the server for the /humans route.

The GET Request Handler Function

Your GET request handler function will receive an ID from the client’s request, search through the database for a row with the ID and return the row’s data from the database as JSON.

The getHuman handler function accesses the data from the request using the Vars function of the mux package and retrieves the ID.

The human variable is an instance of the Human struct created to hold the row’s data with the ID, and the Encode function of the NewEncoder function of the JSON package encodes the human struct instance to the client as a response.

Here’s the CURL request that makes a GET to the server requesting data 1 as the ID.

Here’s the result of the request. The request returns the data inserted into the database with the POST request.

The PUT Request Handler Function

The PUT request handler function would retrieve an ID from the request URL and a JSON payload from the request body and update the ID row with the JSON from the request body.

The updateHuman handler function extracts the ID from the request just like the GET request and retrieves the data with the ID from the database. If the retrieval is successful, the data exists. The Save function of the database instance updates the database with the JSON from the body of the request and returns the JSON to the client after successfully updating the database.

The CURL request for the PUT request holds the payload with different name and age fields from the current data in the database with the ID of 1.

On sending the CURL request, here’s the result of the update operation.

The DELETE Request Handler Function

Your DELETE request handler function would retrieve an ID from the request and delete the row with the ID from the database before responding to the client to signal a successful delete operation.

The deleteHuman function retrieves the ID from the client’s request URL and deletes the row using the Delete function of the database instance.

After a successful deletion operation, the function writes a string with the ID to the client.

Here’s the CURL request for the DELETE request. The client requests to delete the row with ID 1.

On sending the CURL request, here’s the result of the update operation.

Conclusion

You’ve learned about RESTful APIs, the Gorilla Mux package, how to use GORM for persistence when building APIs, how to create router instances, mount routes to handler functions, and how to use the Gorilla Mux package to interact with requests.

Using GORM and Gorilla Mux can help you build scalable, maintainable APIs that handle many HTTP requests efficiently.