Yuen Ying Kit
Posted on April 8, 2019
Originally posted on Boatswain Blog.
In the last post, we have discussed about how we could setup nested templates in Echo framework.
In the following sections, we will move on and see how we could make HTTP request in Echo server and render the result back to the client. Let's start with the example we did in the last article.
Setup an API endpoint
Firstly, create a new API endpoint and return a simple JSON which is later called by the Echo server itself.
Create new endpoint in the api folder
Unlike a hardcoded JSON request, our new API endpoint takes the request input from JSON data, form data or query parameters as defined in the model/example_request.go and then return it the 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),
),
)
}
Setup the route for the above API endpoint
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 as see if it works.
This new endpoint could serve the browser client directly or it could be called by the Echo server itself.
Call the API from Echo server
Create the response struct type
Similar to the model/example_request.go, we need to define another struct type for the HTTP response.
model/example_response.go
package model
type ExampleResponse struct {
FirstName string json:"first_name"
LastName string json:"last_name"
Msg string json:"msg"
}
Show the new greeting message in the about page
Let's modify the about page handler such that it will show the greeting message.
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
Start the Echo server and browse the about page. We could see the new greeting message.
The project structure
After making the above changes, the project structure should look like this. (The project is renamed to handling-http-request-in-go-echo-example-1, make sure you set the import statement in the Golang source files correctly if you want to change the project name.)
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
Summary
This article shows you how to setup a simple API endpoint in Echo framework. Since Go is a strongly typed language, we have to convert the JSON into well defined struct type before for we could manipulate its content. For example:
- Binding the GET request input to exampleRequest in api/get_full_name.go.
- Unmarshal the GET response into exampleResponse in handler/about_handler.go.
To invoke the API call, we could simply make use of the Go standard net/http library.
The complete example could be found on gitlab.com.
Posted on April 8, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
September 27, 2024