Build Your First REST API with Go
Golang Sri Lanka 2020
@imJenal
Image Source: www.calhoun.io/
@imJenal
Application Programming Interface
@imJenal
@imJenal
@imJenal
@imJenal
@imJenal
@imJenal
Image Source: www.uihere.com
Image Source: www.deviantart.com/
@imJenal
@imJenal
package main
import (
"net/http"
)
func main() {
http.ListenAndServe(":3000", nil)
}
main.go
@imJenal
import "github.com/gorilla/mux"
@imJenal
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/", HomeHandler)
router.HandleFunc("/movie/{id}", MovieHandler)
log.Fatal(http.ListenAndServe(":3000", router))
}
main.go
@imJenal
func AllMoviesEndPoint(w http.ResponseWriter, r *http.Request) {}
func FindMovieEndpoint(w http.ResponseWriter, r *http.Request) {}
func CreateMovieEndPoint(w http.ResponseWriter, r *http.Request) {}
func UpdateMovieEndPoint(w http.ResponseWriter, r *http.Request) {}
func DeleteMovieEndPoint(w http.ResponseWriter, r *http.Request) {}
func main() {
router := mux.NewRouter()
router.HandleFunc("/movies", AllMoviesEndPoint).Methods("GET")
router.HandleFunc("/movies", CreateMovieEndPoint).Methods("POST")
router.HandleFunc("/movies", UpdateMovieEndPoint).Methods("PUT")
router.HandleFunc("/movies", DeleteMovieEndPoint).Methods("DELETE")
router.HandleFunc("/movies/{id}", FindMovieEndpoint).Methods("GET")
log.Fatal(http.ListenAndServe(":3000",router))
}
@imJenal
@imJenal
@imJenal
func main() {
router := mux.NewRouter()
allowedHeaders := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"})
allowedMethods := handlers.AllowedMethods([]string{"GET", "POST", "PUT", "HEAD", "OPTIONS"})
allowedOrigins := handlers.AllowedOrigins([]string{*})
log.Fatal(http.ListenAndServe(":3000", handlers.CORS(allowedHeaders, allowedMethods, allowedOrigins)(router)))
}
@imJenal
@imJenal
package main
func Add(value1 int, value2 int) int {
return value1 + value2
}
func main() { }
main.go
@imJenal
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestAdd(t *testing.T) {
total := Add(1, 3)
assert.NotNil(t, total, "" total should not be nil")
assert.Equal(t, 4, total, "Expecting `4`")
}
main_test.go
@imJenal
func TestEndpointGET(t *testing.T) {
request, _ := http.NewRequest("GET", "/create", nil)
response := httptest.NewRecorder()
router := mux.NewRouter()
router.Handle("/create", EndpointGET).Methods("GET")
router.ServeHTTP(response, request)
assert.Equal(t, 200, response.Code, "OK response is expected")
}
@imJenal
func TestEndpointPOST(t *testing.T) {
person := &Person{
Firstname: "Nic",
Lastname: "Raboy"
}
jsonPerson, _ := json.Marshal(person)
request, _ := http.NewRequest("POST", "/create", bytes.NewBuffer(jsonPerson))
response := httptest.NewRecorder()
router := mux.NewRouter()
router.Handle("/create", EndpointPOST).Methods("POST")
router.ServeHTTP(response, request)
assert.Equal(t, 200, response.Code, "OK response is expected")
}
@imJenal
@imJenal
For the REST APIs,
the concrete is better than abstract
/entities
@imJenal
@imJenal
@imJenal
{"errors":[{"code":215,"message":""Bad Authentication data"}]}
@imJenal
@imJenal
https://api.example.com/v1/authors/2/movies/13
@imJenal
https://api.example.com/v2/authors/2/movies/13
@imJenal
https://slides.com/jenal/golangsl2020