Markus Hutnik




Building an API With the Go Standard Library

Intro

Go has a strong standard library. Using this, it is easy to develop a simple REST API without installing any additional dependencies. Although packages like gin are often used, I think it is useful to do exercises like this to understand what Go can offer out of the box. In this article, I'll show how to build a simple API that can handle GET and POST requests using the net/http package which is available as part of the Go standard library.

All the code in this article can be found in GitHub: https://github.com/MarkyMan4/go-rest-api




Getting Started

Create a file called main.go and add the following code.

initial main.go

This is all it takes to get a basic end point running. There are a couple key components in this code. The Book type defines what the JSON data looks like. This is the structure of the JSON that will be returned from the end point. Instead of setting up a database for this toy API, I just created a JSON file with the data I want to work with. The data in that file can be directly read into a Book as well. The data I created can be found here.

The main function sets up handling for different URLs. We can see that when we send a request to /books, the HandleBooks function will be called. Also, the main function starts the web server and tells which port will be used. Based on what is set up here, we would be able to send and HTTP request to http://localhost:5000/books.

The last component is the HandleBooks function. This function contains the code that will run when a request is sent to /books. Since we want the response to be json, the Content-Type is set accordingly in the header of the response. The data is read in from a file (in a real API this would most likely read the data from a database instead). Finally, the data is written to the response.

Now the server can be started with the command:

$ go run main.go

Send a request the end point with this command:

$ curl http://localhost:5000/books

Or to pretty print the JSON, you can pipe the result into json_pp:

$ curl http://localhost:5000/books | json_pp

The response is all the contents of the data.json file.

books get request



Handling HTTP Methods

Now I'll show how to handle both GET and POST request. I'll also show how to handle the case when an HTTP method is used that we do not handle (e.g. PUT, DELETE). I won't put the full code in this article, but it can be found here.

The handle books function should be refactored to simply determine which function to call based on what HTTP method was used. Notice that if the request was not a GET or POST, we'll get a bad request and a message.

new handle books

The code to list the books which was used previously can be moved to a different function which gets called upon receiving a GET request to /books. The code for actually retrieving the books from the "database" (which in this example is just a JSON file) got moved to a separate method as well. Again, the full code can be viewed in GitHub to see how the data is retrieved from the JSON file.

list books

Finally, we have the CreateBook function which is called when a POST request is sent to /books. This function expects JSON to come in the body of the request which has the fields we need to create a book. If any errors happen while reading the body or trying to unmarshal the body into a Book type, an appropriate message will be written to the response. If successful, this method will return a 201 response to indicate that the book was successfully created. The book that was created will also get sent in the body of the response.

create book



Testing

The method I showed previously for getting all the books can be used the same as earlier:

$ curl http://localhost:5000/books

To create a book, the following request can be made:

$ curl -X POST --data '{"id": 7, "title": "test title", "author": "test author", "publicationYear": 2000, "genre": "horror"}' http://localhost:5000/books

If successful, the response will contain the data that was passed in the body.

create response

Finally, we can make another GET request and see the newly created item shows up.

new book in response



Conclusion

In this article, I've shown how to create a simple REST API using only the Go standard library. I wrote this article to show what can be accomplished without relying on any third-party libraries and to show how Go keeps things simple. I'm still learning Go myself, so I think it is good to understand how an API can be written in pure Go. It helps provide a better understanding of what is happening under the hood when using a package like gin.