In this article, it will show you how to create a simple REST API using Golang and Mux. Mux is a router that will allow us to handle the HTTP requests that we are going to receive in our API.
Gorilla Mux library
In our Rest API, we are going to use the external libraries that is Gorilla Mux. Gorilla is a web toolkit that provide multiple packages, and one of them is Mux and that’s the one that we’re going to use. Mux is a powerful URL router and dispatcher. We’re gonna see how it works but basically we are going to be able to map the paths and the HTTP methods to a function that we’re going to implement.
Create Project
When your code imports packages contained in other modules, you manage those dependencies through your code’s own module. That module is defined by a go.mod
file that tracks the modules that provide those packages. That go.mod
file stays with your code, including in your source code repository.
To enable dependency tracking for your code by creating a go.mod file, run the go mod init
command, giving it the name of the module your code will be in. The name is the module’s module path.
In actual development, the module path will typically be the repository location where your source code will be kept. For example, the module path might be github.com/mymodule
. If you plan to publish your module for others to use, the module path must be a location from which Go tools can download your module. For more about naming a module with a module path, see Managing dependencies.
For the purposes of this tutorial, just use golang-mux-api
.
$ cd $GOPATH/src
$ mkdir golang-mux-api
$ cd golang-mux-api
$ go mod init golang-mux-api
Install Mux library
Run the bellow command to install Max dependency or Mux library
$ go get -u github.com/gorilla/mux
Setup Simple REST Server
First step here is going to create a file that is going to be the entry point of our application I’m going to call it server.go with the content as bellow:
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
const port string = ":8000"
router.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
fmt.Fprint(resp, "Up and running...")
})
log.Println("Server listening on port", port)
log.Fatalln(http.ListenAndServe(port, router))
}
Then we need to try go build:
$ go build
If there is no errors then we can run it:
$ go run .
or
$ go run *.go
Then in the terminal we can see the log:
2023/03/13 23:04:46 Server listening on port :8000
Now we have our server is up and running on port 8000, and I am going to execute the request:
$ curl -v http://localhost:8000
* Trying 127.0.0.1:8000...
* Connected to localhost (::1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
< HTTP/1.1 200 OK
< { [17 bytes data]
Up and running...
Create Post Rest APIs
First, we need to create a structure (struct) that is going to be a “Post” structure that is going to include an identifier, a title and a text.
type Post struct {
Id int `json:"id"`
Title string `json:"title"`
Text string `json:"text"`
}
This structure is going to represent the requests and the response by returning these posts using a JSON format. Then i am going to create new post receving a JSON as part of the payload (request) . In order to be able to encode and decode this struct in JSON format (to JSON format and from the JSON format), I need to import the encoding library for JSON as follow:
import (
"encoding/json"
)
And we need to add some handler functions for “/posts” with method GET to return all posts, and method POST to create new post. We have the full source code of new file “route.go” as follow:
package main
import (
"encoding/json"
"net/http"
)
type Post struct {
Id int `json:"id"`
Title string `json:"title"`
Text string `json:"text"`
}
var (
posts []Post
)
func init() {
posts = []Post{Post{Id: 1, Title: "Title 1", Text: "Text 1"}}
}
func getPosts(resp http.ResponseWriter, req *http.Request) {
resp.Header().Set("Content-type", "application/json")
result, err := json.Marshal(posts)
if err != nil {
resp.WriteHeader(http.StatusInternalServerError)
resp.Write([]byte(`{"error": "Error marshalling the posts array"}`))
return
}
resp.WriteHeader(http.StatusOK)
resp.Write(result)
}
func addPost(resp http.ResponseWriter, req *http.Request) {
resp.Header().Set("Content-type", "application/json")
var post Post
err := json.NewDecoder(req.Body).Decode(&post)
if err != nil {
resp.WriteHeader(http.StatusInternalServerError)
resp.Write([]byte(`{"error": "Error unmarshalling the request"}`))
return
}
post.Id = len(posts) + 1
posts = append(posts, post)
resp.WriteHeader(http.StatusOK)
result, err := json.Marshal(post)
if err != nil {
resp.WriteHeader(http.StatusInternalServerError)
resp.Write([]byte(`{"error": "Error unmarshalling the request Body"}`))
return
}
resp.Write(result)
}
Finally, we need to add the mapping for these 2 handler functions in the file “server.go” as follow:
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
const port string = ":8000"
router.HandleFunc("/", func(resp http.ResponseWriter, request *http.Request) {
fmt.Fprint(resp, "Up and running...")
})
router.HandleFunc("/posts", getPosts).Methods("GET")
router.HandleFunc("/posts", addPost).Methods("POST")
log.Println("Server listening on port", port)
log.Fatalln(http.ListenAndServe(port, router))
}
Test the Post REST APIs
Build and run the server
$ go build
$ go run .
Then you can use cURL to test our Post REST APIs
First we create a new post
$ curl -v --location 'http://localhost:8000/posts' --header 'Content-Type: application/json' --data '{
"title": "Title 1",
"text": "Text 1"
}'
* Trying 127.0.0.1:8000...
* Connected to localhost (::1) port 8000 (#0)
> POST /posts HTTP/1.1
> Host: localhost:8000
>
} [48 bytes data]
< HTTP/1.1 200 OK
<
{ [42 bytes data]
{"id":1,"title":"Title 1","text":"Text 1"}
Then we list all posts
$ curl -v --location 'http://localhost:8000/posts'
* Trying 127.0.0.1:8000...
* Connected to localhost (::1) port 8000 (#0)
> GET /posts HTTP/1.1
> Host: localhost:8000
< HTTP/1.1 200 OK
<
{ [44 bytes data]
[{"id":1,"title":"Title 1","text":"Text 1"}]
Download Source Code
$ git clone https://github.com/favtuts/golang-mux-api.git
$ cd golang-mux-api
$ go build$ go run .