├── .gitignore ├── README.md ├── main.go └── run.sh /.gitignore: -------------------------------------------------------------------------------- 1 | go_simple_rest_api.exe 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple GO Lang REST API 2 | 3 | > Simple RESTful API to create, read, update and delete books. No database implementation yet 4 | 5 | ## Quick Start 6 | 7 | 8 | ``` bash 9 | # Install mux router 10 | go get -u github.com/gorilla/mux 11 | ``` 12 | 13 | ``` bash 14 | go build 15 | ./go_restapi 16 | ``` 17 | 18 | ## Endpoints 19 | 20 | ### Get All Books 21 | ``` bash 22 | GET api/books 23 | ``` 24 | ### Get Single Book 25 | ``` bash 26 | GET api/books/{id} 27 | ``` 28 | 29 | ### Delete Book 30 | ``` bash 31 | DELETE api/books/{id} 32 | ``` 33 | 34 | ### Create Book 35 | ``` bash 36 | POST api/books 37 | 38 | # Request sample 39 | # { 40 | # "isbn":"4545454", 41 | # "title":"Book Three", 42 | # "author":{"firstname":"Harry", "lastname":"White"} 43 | # } 44 | ``` 45 | 46 | ### Update Book 47 | ``` bash 48 | PUT api/books/{id} 49 | 50 | # Request sample 51 | # { 52 | # "isbn":"4545454", 53 | # "title":"Updated Title", 54 | # "author":{"firstname":"Harry", "lastname":"White"} 55 | # } 56 | 57 | ``` 58 | 59 | 60 | ``` 61 | 62 | ## App Info 63 | 64 | ### Author 65 | 66 | Brad Traversy 67 | [Traversy Media](http://www.traversymedia.com) 68 | 69 | ### Version 70 | 71 | 1.0.0 72 | 73 | ### License 74 | 75 | This project is licensed under the MIT License 76 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "math/rand" 7 | "net/http" 8 | "strconv" 9 | 10 | "github.com/gorilla/mux" 11 | ) 12 | 13 | // Book struct (Model) 14 | type Book struct { 15 | ID string `json:"id"` 16 | Isbn string `json:"isbn"` 17 | Title string `json:"title"` 18 | Author *Author `json:"author"` 19 | } 20 | 21 | // Author struct 22 | type Author struct { 23 | Firstname string `json:"firstname"` 24 | Lastname string `json:"lastname"` 25 | } 26 | 27 | // Init books var as a slice Book struct 28 | var books []Book 29 | 30 | // Get all books 31 | func getBooks(w http.ResponseWriter, r *http.Request) { 32 | w.Header().Set("Content-Type", "application/json") 33 | json.NewEncoder(w).Encode(books) 34 | } 35 | 36 | // Get single book 37 | func getBook(w http.ResponseWriter, r *http.Request) { 38 | w.Header().Set("Content-Type", "application/json") 39 | params := mux.Vars(r) // Gets params 40 | // Loop through books and find one with the id from the params 41 | for _, item := range books { 42 | if item.ID == params["id"] { 43 | json.NewEncoder(w).Encode(item) 44 | return 45 | } 46 | } 47 | json.NewEncoder(w).Encode(&Book{}) 48 | } 49 | 50 | // Add new book 51 | func createBook(w http.ResponseWriter, r *http.Request) { 52 | w.Header().Set("Content-Type", "application/json") 53 | var book Book 54 | _ = json.NewDecoder(r.Body).Decode(&book) 55 | book.ID = strconv.Itoa(rand.Intn(100000000)) // Mock ID - not safe 56 | books = append(books, book) 57 | json.NewEncoder(w).Encode(book) 58 | } 59 | 60 | // Update book 61 | func updateBook(w http.ResponseWriter, r *http.Request) { 62 | w.Header().Set("Content-Type", "application/json") 63 | params := mux.Vars(r) 64 | for index, item := range books { 65 | if item.ID == params["id"] { 66 | books = append(books[:index], books[index+1:]...) 67 | var book Book 68 | _ = json.NewDecoder(r.Body).Decode(&book) 69 | book.ID = params["id"] 70 | books = append(books, book) 71 | json.NewEncoder(w).Encode(book) 72 | return 73 | } 74 | } 75 | } 76 | 77 | // Delete book 78 | func deleteBook(w http.ResponseWriter, r *http.Request) { 79 | w.Header().Set("Content-Type", "application/json") 80 | params := mux.Vars(r) 81 | for index, item := range books { 82 | if item.ID == params["id"] { 83 | books = append(books[:index], books[index+1:]...) 84 | break 85 | } 86 | } 87 | json.NewEncoder(w).Encode(books) 88 | } 89 | 90 | // Main function 91 | func main() { 92 | // Init router 93 | r := mux.NewRouter() 94 | 95 | // Hardcoded data - @todo: add database 96 | books = append(books, Book{ID: "1", Isbn: "438227", Title: "Book One", Author: &Author{Firstname: "John", Lastname: "Doe"}}) 97 | books = append(books, Book{ID: "2", Isbn: "454555", Title: "Book Two", Author: &Author{Firstname: "Steve", Lastname: "Smith"}}) 98 | 99 | // Route handles & endpoints 100 | r.HandleFunc("/books", getBooks).Methods("GET") 101 | r.HandleFunc("/books/{id}", getBook).Methods("GET") 102 | r.HandleFunc("/books", createBook).Methods("POST") 103 | r.HandleFunc("/books/{id}", updateBook).Methods("PUT") 104 | r.HandleFunc("/books/{id}", deleteBook).Methods("DELETE") 105 | 106 | // Start server 107 | log.Fatal(http.ListenAndServe(":8000", r)) 108 | } 109 | 110 | // Request sample 111 | // { 112 | // "isbn":"4545454", 113 | // "title":"Book Three", 114 | // "author":{"firstname":"Harry","lastname":"White"} 115 | // } 116 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | nohup ./go_restapi > nohup.out 2>&1 & 3 | --------------------------------------------------------------------------------