Manipulating HTTP requests in the Go Echo framework(1)
Update @ 2019-12-13: As of Go 1.13, use the built-in Go Module to manage suites.
In the previous article, we discussed how to set up nested boilerplates in the Echo framework.
In the next sections, we'll move on to how to make an HTTP request in the Echo server and render the result on the client. Let's start with the example from the previous article.
Set up API endpoints
First, create a new API endpoint to return a simple JSON that will later be called by the Echo server itself.
Create a new endpoint in the api folder
Unlike hard-coded JSON requests, the request structure of this new API endpoint will be defined in the file model/example_request.go , and its content can be provided as a JSON object, HTML table, or URL parameters when implemented, and then return it to the client.
model/example_request.go
package model type ExampleRequest struct { FirstName string `json:"first_name" form:"first_name" query:"first_name"` LastName string `json:"last_name" form:"last_name" query:"last_name"` }
api/get_full_name.go
package api import ( "fmt" "net/http" "github.com/labstack/echo" "gitlab.com/ykyuen/golang-echo-template-example/model" ) func GetFullName(c echo.Context) error { // Bind the input data to ExampleRequest exampleRequest := new(model.ExampleRequest) if err := c.Bind(exampleRequest); err != nil { return err } // Manipulate the input data greeting := exampleRequest.FirstName + " " + exampleRequest.LastName return c.JSONBlob( http.StatusOK, []byte( fmt.Sprintf(`{ "first_name": %q, "last_name": %q, "msg": "Hello %s" }`, exampleRequest.FirstName, exampleRequest.LastName, greeting), ), ) }
Set up routes for the above API endpoints
Add our new API endpoint route in main.go
... func main() { // Echo instance e := echo.New() // Instantiate a template registry with an array of template set // Ref: https://gist.github.com/rand99/808e6e9702c00ce64803d94abff65678 templates := make(map[string]*template.Template) templates["home.html"] = template.Must(template.ParseFiles("view/home.html", "view/base.html")) templates["about.html"] = template.Must(template.ParseFiles("view/about.html", "view/base.html")) e.Renderer = &TemplateRegistry{ templates: templates, } // Route => handler e.GET("/", handler.HomeHandler) e.GET("/about", handler.AboutHandler) // Route => api e.GET("/api/get-full-name", api.GetFullName) // Start the Echo server e.Logger.Fatal(e.Start(":1323")) }
Test the new API endpoint
Run the Echo server to test it out.
This new endpoint can serve browsers or other clients directly, or it can be called by the Echo server itself.
Call API from Echo server
Create Response Structure Types
Similar to model/example_request.go , we need to define an HTTP response structure type.
model/example_response.go
package model type ExampleResponse struct { FirstName string `json:"first_name"` LastName string `json:"last_name"` Msg string `json:"msg"` }
Display response information on the about page
Modify the code in about handler to display information about the HTTP response.
handler/about_handler.go
package handler import ( "encoding/json" "io/ioutil" "net/http" "github.com/labstack/echo" "gitlab.com/ykyuen/golang-echo-template-example/model" ) func AboutHandler(c echo.Context) error { tr := &http.Transport{} client := &http.Client{Transport: tr} // call the api resp, err := client.Get( "http://localhost:1323/api/get-full-name?first_name=Kit&last_name=Yuen", ) if err != nil { return err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) // Unmarshal the response into a ExampleResponse struct var exampleResponse model.ExampleResponse if err = json.Unmarshal(body, &exampleResponse); err != nil { return err } // Please note the the second parameter "about.html" is the template name and should // be equal to one of the keys in the TemplateRegistry array defined in main.go return c.Render(http.StatusOK, "about.html", map[string]interface{}{ "name": "About", "msg": exampleResponse.Msg, }) }
Test the about page
Starting the Echo server and browsing the about page, we can see the new greeting.
Project structure
After making the above changes, the project structure should look like the image below. (The project is renamed to handling-http-request-in-go-echo-example-1 . If you want to change the project name, make sure to set the import statement in the Golang code correctly.)
handling-http-request-in-go-echo-example-1/ ├── api/ # folder of api endpoints │ ├── get_full_name.go # api for get full name ├── handler/ # folder of request handlers │ ├── home_handler.go # handler for home page │ └── about_handler.go # handler for about page ├── model/ # folder of custom struct types │ ├── example_request.go # struct type of get_full_name request │ └── example_response.go # hstruct type of get_full_name response ├── vendor/ # dependencies managed by dep │ ├── github.com/* │ └── golang.org/* ├── view/ # folder of html templates │ ├── base.html # base layout template │ ├── home.html # home page template │ └── about.html # about page template ├── Gopkg.lock # dep config file ├── Gopkg.toml # dep config file └── main.go # programme entrypoint
Summarize
This article describes how to set up a simple API endpoint in the Echo framework. Since Go is a strongly typed language, we must type the structure of the JSON request and response before we can manipulate its content. E.g:
- Bind a GET request to exampleRequest at api/ get_full_name.go.
- Unmarshal the GET response into exampleResponse at handler/ about_handler.go .
To call the API, we can directly use the built-in net/http standard library of Go .
The full example can be found on this gitlab.com repository .
Like my work? Don't forget to support and clap, let me know that you are with me on the road of creation. Keep this enthusiasm together!
- Author
- More