Last active
October 9, 2021 14:18
-
-
Save soyart/bc1c1e614c43800855ebdf9436fb95d2 to your computer and use it in GitHub Desktop.
Basic REST API server in Go using gorilla/mux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "bytes" | |
| "encoding/json" | |
| "log" | |
| "net/http" | |
| "github.com/google/uuid" | |
| "github.com/gorilla/mux" | |
| ) | |
| func main() { | |
| router := mux.NewRouter() | |
| router.HandleFunc("/artists", getArtists).Methods("GET") | |
| router.HandleFunc("/artists", createArtist).Methods("POST") | |
| router.HandleFunc("/artists/{id}", getArtist).Methods("GET") | |
| router.HandleFunc("/artists/{id}", deleteArtist).Methods("DELETE") | |
| router.HandleFunc("/albums", getAlbums).Methods("GET") | |
| router.HandleFunc("/albums", createAlbum).Methods("POST") | |
| router.HandleFunc("/albums/{id}", getAlbum).Methods("GET") | |
| router.HandleFunc("/albums/{id}", deleteAlbum).Methods("DELETE") | |
| log.Fatal(http.ListenAndServe(":8000", router)) | |
| } | |
| func getArtists(w http.ResponseWriter, r *http.Request) { | |
| log.Println("Endpoint hit: GET /artists") | |
| json.NewEncoder(w).Encode(artists) | |
| } | |
| func getArtist(w http.ResponseWriter, r *http.Request) { | |
| log.Println("Endpoint hit: GET /artists/id") | |
| var found bool | |
| vars := mux.Vars(r) | |
| targetId := vars["id"] | |
| for _, artist := range artists { | |
| if artist.Id == targetId { | |
| found = true | |
| json.NewEncoder(w).Encode(artist) | |
| } | |
| } | |
| if !found { | |
| w.WriteHeader(http.StatusNotFound) | |
| } | |
| } | |
| func createArtist(w http.ResponseWriter, r *http.Request) { | |
| log.Println("Endpoint hit: POST /artists") | |
| reqBody := new(bytes.Buffer) | |
| reqBody.ReadFrom(r.Body) | |
| defer r.Body.Close() | |
| var newArtist Artist | |
| json.Unmarshal(reqBody.Bytes(), &newArtist) | |
| newArtist.Id = uuid.NewString() | |
| artists = append(artists, newArtist) | |
| json.NewEncoder(w).Encode(newArtist) | |
| } | |
| func deleteArtist(w http.ResponseWriter, r *http.Request) { | |
| log.Println("Endpoint hit: DELETE /artists/id") | |
| var found bool | |
| vars := mux.Vars(r) | |
| targetId := vars["id"] | |
| for idx, artist := range artists { | |
| if artist.Id == targetId { | |
| found = true | |
| artists = append(artists[:idx], artists[idx+1:]...) | |
| } | |
| } | |
| if found { | |
| json.NewEncoder(w).Encode(artists) | |
| } else { | |
| w.WriteHeader(http.StatusNotFound) | |
| } | |
| } | |
| func getAlbums(w http.ResponseWriter, r *http.Request) { | |
| log.Println("Endpoint hit: GET /albums") | |
| json.NewEncoder(w).Encode(albums) | |
| } | |
| func getAlbum(w http.ResponseWriter, r *http.Request) { | |
| log.Println("Endpoint hit: GET /albums/id") | |
| var found bool | |
| vars := mux.Vars(r) | |
| targetId := vars["id"] | |
| for _, album := range albums { | |
| if album.Id == targetId { | |
| found = true | |
| json.NewEncoder(w).Encode(album) | |
| } | |
| } | |
| if !found { | |
| w.WriteHeader(http.StatusNotFound) | |
| } | |
| } | |
| func createAlbum(w http.ResponseWriter, r *http.Request) { | |
| log.Println("Endpoint hit: POST /albums") | |
| reqBody := new(bytes.Buffer) | |
| reqBody.ReadFrom(r.Body) | |
| defer r.Body.Close() | |
| var albumReq ReqAlbum | |
| var foundArtist bool | |
| json.Unmarshal(reqBody.Bytes(), &albumReq) | |
| for _, artist := range artists { | |
| if albumReq.ArtistId == artist.Id { | |
| foundArtist = true | |
| targetArtist = artist | |
| newAlbum := newAlbum(albumReq.Title, artist, albumReq.Price) | |
| json.NewEncoder(w).Encode(newAlbum) | |
| albums = append(albums, newAlbum) | |
| } | |
| } | |
| if !foundArtist { | |
| w.WriteHeader(http.StatusNotFound) | |
| w.Write([]byte("Artist not found")) | |
| } | |
| } | |
| func deleteAlbum(w http.ResponseWriter, r *http.Request) { | |
| log.Println("Endpoint hit: /DELETE /albums") | |
| var found bool | |
| vars := mux.Vars(r) | |
| targetId := vars["id"] | |
| log.Println(targetId) | |
| for idx, album := range albums { | |
| if album.Id == targetId { | |
| found = true | |
| albums = append(albums[:idx], albums[idx+1:]...) | |
| } | |
| } | |
| if found { | |
| json.NewEncoder(w).Encode(albums) | |
| } else { | |
| w.WriteHeader(http.StatusNotFound) | |
| } | |
| } | |
| type Artist struct { | |
| Id string `json:"artistId"` | |
| Name string `json:"artistName"` | |
| Country string `json:"country"` | |
| IsBand bool `json:"isBand"` | |
| } | |
| type Album struct { | |
| Id string `json:"albumId"` | |
| Title string `json:"title"` | |
| Artist Artist `json:"artist"` | |
| Price float64 `json:"price"` | |
| } | |
| type ReqAlbum struct { | |
| Title string `json:"title"` | |
| ArtistId string `json:"artistId"` | |
| Price float64 `json:"price"` | |
| } | |
| func newArtist(name string, country string, isBand bool) Artist { | |
| return Artist{ | |
| Id: uuid.New().String(), // .NewString() | |
| Name: name, | |
| Country: country, | |
| IsBand: isBand, | |
| } | |
| } | |
| func newAlbum(title string, artist Artist, price float64) Album { | |
| return Album{ | |
| Id: uuid.NewString(), | |
| Title: title, | |
| Artist: artist, | |
| Price: price, | |
| } | |
| } | |
| var ( | |
| pinkFloyd = newArtist("Pink Floyd", "UK", true) | |
| rush = newArtist("Rush", "Canada", true) | |
| artists = []Artist{pinkFloyd, rush} | |
| albums = []Album{ | |
| newAlbum("The Wall", pinkFloyd, 50), | |
| newAlbum("Wish You Were Here", pinkFloyd, 39), | |
| newAlbum("2112", rush, 40), | |
| } | |
| ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment