Skip to content

Instantly share code, notes, and snippets.

@bynect
Last active January 24, 2021 19:51
Show Gist options
  • Save bynect/1ad429cada23fbe2eb2110da2ae1114e to your computer and use it in GitHub Desktop.
Save bynect/1ad429cada23fbe2eb2110da2ae1114e to your computer and use it in GitHub Desktop.
Simple RESTful API made in Go with Mux.
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/google/uuid"
"github.com/gorilla/mux"
)
//Book Model
type Book struct {
ID uuid.UUID `json:"id"`
Isbn string `json:"isbn"`
Title string `json:"title"`
Author *Author `json:"author"`
}
//Author Model
type Author struct {
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
}
//Error Model
type Error struct {
Description string `json:"error"`
Code int `json:"code"`
}
//Book var as slice
var books []Book
//Request handling funcs
//Get all books
func getBooks(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "application/json")
json.NewEncoder(res).Encode(books)
log.Print("GET api/v1/books")
}
//Get book by ID
func getBook(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "application/json")
params := mux.Vars(req)
//Loop trough books
for _, item := range books {
id, err := uuid.Parse(params["id"])
if err != nil {
json.NewEncoder(res).Encode(&Error{Description: "Invalid Book ID", Code: 404})
return
}
if item.ID == id {
json.NewEncoder(res).Encode(item)
return
}
}
json.NewEncoder(res).Encode(&Book{})
log.Printf("GET api/v1/books/%s", params["id"])
}
//Create book
func createBook(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "application/json")
var book Book
_ = json.NewDecoder(req.Body).Decode(&book)
book.ID = uuid.New()
books = append(books, book)
json.NewEncoder(res).Encode(book)
log.Print("POST api/v1/books")
}
//Update book by ID
func updateBook(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "application/json")
params := mux.Vars(req)
for index, item := range books {
id, err := uuid.Parse(params["id"])
if err != nil {
json.NewEncoder(res).Encode(&Error{Description: "Invalid Book ID", Code: 400})
return
}
if item.ID == id {
books = append(books[:index], books[index+1:]...)
var book Book
_ = json.NewDecoder(req.Body).Decode(&book)
book.ID = id
books = append(books, book)
json.NewEncoder(res).Encode(book)
return
}
}
json.NewEncoder(res).Encode(books)
log.Printf("GET api/v1/books/%s", params["id"])
}
//Delete book by ID
func deleteBook(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "application/json")
params := mux.Vars(req)
for index, item := range books {
id, err := uuid.Parse(params["id"])
if err != nil {
json.NewEncoder(res).Encode(&Error{Description: "Invalid Book ID", Code: 400})
return
}
if item.ID == id {
books = append(books[:index], books[index+1:]...)
break
}
}
json.NewEncoder(res).Encode(books)
log.Printf("GET api/v1/books/%s", params["id"])
}
//Main function
func main() {
//Init Router
router := mux.NewRouter()
//Test data
books = append(books, Book{ID: uuid.New(), Isbn: "AB343434C", Title: "Bokker", Author: &Author{Firstname: "John", Lastname: "Doe"}})
//Route Handlers -> Endpoints
router.HandleFunc("/api/v1/books", getBooks).Methods("GET")
router.HandleFunc("/api/v1/books/{id}", getBook).Methods("GET")
router.HandleFunc("/api/v1/books", createBook).Methods("POST")
router.HandleFunc("/api/v1/books/{id}", updateBook).Methods("PUT")
router.HandleFunc("/api/v1/books/{id}", deleteBook).Methods("DELETE")
log.Fatal(http.ListenAndServe(":8000", router))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment