REST API with Go: Practical Examples
Examples of Building a REST API with Go
Building a REST API with Go can be a straightforward task, thanks to its robust standard library and third-party packages. Below are three practical examples demonstrating how to create a basic REST API using Go. Each example addresses different use cases and provides code snippets to help you understand the implementation.
Example 1: Simple Todo List API
Context
This example demonstrates how to create a simple REST API for managing a todo list. The API allows users to create, read, update, and delete todo items.
package main
import (
"encoding/json"
"net/http"
"sync"
)
type Todo struct {
ID int `json:"id"`
Title string `json:"title"`
Done bool `json:"done"`
}
var (
todos = make(map[int]Todo)
nextID = 1
mu sync.Mutex
)
func getTodos(w http.ResponseWriter, r *http.Request) {
mu.Lock()
defer mu.Unlock()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(todos)
}
func createTodo(w http.ResponseWriter, r *http.Request) {
var todo Todo
if err := json.NewDecoder(r.Body).Decode(&todo); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
mu.Lock()
todo.ID = nextID
nextID++
todos[todo.ID] = todo
mu.Unlock()
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(todo)
}
func main() {
http.HandleFunc("/todos", getTodos)
http.HandleFunc("/todos/create", createTodo)
http.ListenAndServe(":8080", nil)
}
Notes
- You can extend this API by adding update and delete functionalities.
- For persistence, consider integrating a database.
Example 2: Book Management API with CRUD Operations
Context
This example illustrates how to implement a REST API for managing books in a library. The API supports create, read, update, and delete operations.
package main
import (
"encoding/json"
"net/http"
"sync"
)
type Book struct {
ID int `json:"id"`
Title string `json:"title"`
Author string `json:"author"`
}
var (
books = make(map[int]Book)
nextID = 1
mu sync.Mutex
)
func getBooks(w http.ResponseWriter, r *http.Request) {
mu.Lock()
defer mu.Unlock()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(books)
}
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
}
mu.Lock()
book.ID = nextID
nextID++
books[book.ID] = book
mu.Unlock()
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(book)
}
func updateBook(w http.ResponseWriter, r *http.Request) {
// Implement update logic here
}
func deleteBook(w http.ResponseWriter, r *http.Request) {
// Implement delete logic here
}
func main() {
http.HandleFunc("/books", getBooks)
http.HandleFunc("/books/create", createBook)
// Add handlers for update and delete
http.ListenAndServe(":8080", nil)
}
Notes
- Consider using route parameters for the update and delete functions.
- Implementing a database connection will enhance data persistence.
Example 3: User Authentication API
Context
In this example, we will create a simple user authentication API. Users can register and log in, receiving a token for subsequent requests.
package main
import (
"encoding/json"
"net/http"
"sync"
)
type User struct {
Username string `json:"username"`
Password string `json:"password"`
}
var (
users = make(map[string]string)
mu sync.Mutex
)
func registerUser(w http.ResponseWriter, r *http.Request) {
var user User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
mu.Lock()
users[user.Username] = user.Password
mu.Unlock()
w.WriteHeader(http.StatusCreated)
}
func loginUser(w http.ResponseWriter, r *http.Request) {
var user User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
mu.Lock()
password, exists := users[user.Username]
mu.Unlock()
if !exists || password != user.Password {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode("Login successful")
}
func main() {
http.HandleFunc("/register", registerUser)
http.HandleFunc("/login", loginUser)
http.ListenAndServe(":8080", nil)
}
Notes
- For real-world applications, consider using hashed passwords and tokens for user sessions.
- Implement JWT for a more secure authentication mechanism.
These examples provide a foundation for building various REST APIs using Go. You can expand upon these by integrating databases, adding more sophisticated error handling, and enhancing security measures.
Related Topics
Explore More Go Code Snippets
Discover more examples and insights in this category.
View All Go Code Snippets