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