Building Your First REST API with Go – Let’s Get Started!
So, you’ve heard the buzz about Go, right? It’s fast, it’s simple, and it’s basically the rockstar of backend development these days. If you’re new to Go or just looking to build something cool with it, you’ve come to the right place. This week, we’re going to take a dive into building your very own REST API with Go, so buckle up—it’s gonna be a fun ride!
Why Go?
Now, why exactly are so many devs swooning over Go? Well, imagine this: Google engineers, tired of waiting around for their programs to compile, decided to create something that wouldn't make them want to tear their hair out. Enter Go—a language that doesn’t just get the job done but does it fast and effortlessly.
Go is built for today’s hardware, taking full advantage of multi-core systems. Its secret weapon? Goroutines—these magical little concurrent workers that can handle tons of tasks simultaneously without breaking a sweat. Whether you’re building web apps, APIs, or microservices, Go keeps things running smoothly, like that well-oiled machine you always dream of.
And here’s the kicker: Go is stupidly easy to learn. Whether you’re switching over from Python, Java, or even something as “classic” as PHP, you’ll be up and coding in Go before you can say "Hello, World!" And it runs fast—like, really fast. Need I say more?
Setting Up Your Go Project
Alright, enough chit-chat, let’s get our hands dirty. First, we need to set up a simple Go project. Don’t worry, I’ve got you covered:
Make sure Go is installed. If not, grab it here.
Now, let’s create a project directory and initialize the project:
mkdir go-rest-api
cd go-rest-api
go mod init github.com/yourusername/go-rest-api
- Inside this directory, create a new file called
main.go
, and get ready for some coding magic.
Writing the API
Here’s where things get exciting! We’re going to build a super simple API to manage a list of books (because who doesn’t love books?). Our API will have the following endpoints:
-
GET /books
– Fetch all the books (yay, books!) -
POST /books
– Add a new book -
GET /books/:id
– Fetch a specific book by its ID (because not all books are created equal)
Ready? Let’s dive into the code:
Get the gorilla/mux http router using this command:
go get -u github.com/gorilla/mux
In the main.go file:
package main
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
"github.com/gorilla/mux"
)
type Book struct {
ID int `json:"id"`
Title string `json:"title"`
Author string `json:"author"`
}
var books []Book
func getBooks(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(books)
}
func getBook(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id, err := strconv.Atoi(params["id"])
if err != nil {
http.Error(w, "Invalid book ID", http.StatusBadRequest)
return
}
if id == 0 {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(books)
return
}
// find the book with the given id
for _, book := range books {
if book.ID == id {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(book)
return
}
}
http.Error(w, "Book not found", http.StatusNotFound)
}
// Add a new book
func createBook(w http.ResponseWriter, r *http.Request) {
var book Book
_ = json.NewDecoder(r.Body).Decode(&book)
if book.Author == "" || book.Title == "" {
http.Error(w, "Please provide a title and an author", http.StatusBadRequest)
return
}
book.ID = len(books) + 1 // Assign an ID (we’re just winging it here)
books = append(books, book)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(book)
}
func main() {
// Add some dummy data to start with
books = append(books, Book{ID: 1, Title: "The Go Programming Language", Author: "Alan A. A. Donovan"})
books = append(books, Book{ID: 2, Title: "Learning Go", Author: "Jon Bodner"})
// Initialize the router
r := mux.NewRouter()
// Define the endpoints
r.HandleFunc("/books/", getBooks).Methods("GET")
r.HandleFunc("/books/{id}", getBook).Methods("GET")
r.HandleFunc("/books", createBook).Methods("POST")
// Start the server
fmt.Println("Server is running on port 8000...")
log.Fatal(http.ListenAndServe(":8000", r))
}
Breaking It Down
-
Mux Router: We’re using
gorilla/mux
to handle routing in our API. It makes it easy to define routes and is a go-to for building web services in Go. You can install it with:
go get -u github.com/gorilla/mux
Handlers: We’ve set up
getBooks
,getBook
, andcreateBook
functions to handle HTTP requests. They use Go’snet/http
package to handle responses and data encoding/decoding. Easy-peasy!JSON Encoding: Go’s built-in
json
package is doing the heavy lifting here, converting our data into JSON format for easy communication between the client and the API.
Running the API
Now for the fun part—let’s run this thing! In your terminal, simply execute:
go run main.go
Boom! Your API is up and running. You can now use tools like Postman or curl
to test it:
- Get all books:
curl http://localhost:8000/books
- Get a specific book:
curl http://localhost:8000/books/1
- Add a new book:
curl -X POST http://localhost:8000/books -d '{"title":"New Book","author":"New Author"}' -H "Content-Type: application/json"
What’s Next?
This little API is just the tip of the iceberg when it comes to what Go can do in backend development. Next week, we’ll level up by adding authentication (yep, we’re going full JWT) and protecting these endpoints from unwanted visitors.
Stay tuned for part 2 -- Setting up middleware for authentication in a REST API using JWT (JSON Web Tokens) in Go
Top comments (2)
Upvoted ... I would rather say "Go is surprisingly easy to learn" :-) . So far, I did not have time/motivation/challenges/etc... to work on go/golang projects, and yet the code I see in your examples looks familiar. An interesting read, many thanks ... BTW, please have a look at your JWT article, it seems that the content is lost somehow.
Thanks for the upvote! You're absolutely right—Go is surprisingly easy to learn, and I’m glad the examples feel familiar even if you haven’t worked with Go before. That’s one of the reasons why I’m a big fan of it, it just clicks!
As for the JWT article, thanks for the heads-up! I’ll take a look and make sure everything is back in place. Really appreciate the feedback and glad you found the post interesting.