Yuen Ying Kit
Posted on April 18, 2019
Originally posted on Boatswain Blog.
This is the second post about handling HTTP request in Echo framework and we will continue to work on the example we made previously.
This time we will create a simple HTML form and submit it as a POST request.
Create a POST request endpoint
Checkout this repo and create the api/post_full_name.go to handle the POST request. This new file is almost the same as api/get_full_name.go except the JSON is prettified before returning to the client.
api/post_full_name.go
package api
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"github.com/labstack/echo"
"gitlab.com/ykyuen/handling-http-request-in-go-echo-example-1/model"
)
func PostFullName(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
// Pretty print the json []byte
var resp bytes.Buffer
var b = []byte(
fmt.Sprintf(`{
"first_name": %q,
"last_name": %q,
"msg": "Hello %s"
}`, exampleRequest.FirstName, exampleRequest.LastName, greeting),
)
err := json.Indent(&resp, b, "", " ")
if err != nil {
return err
}
// Return the json to the client
return c.JSONBlob(
http.StatusOK,
[]byte(
fmt.Sprintf("%s", resp.Bytes()),
),
)
}
Add the new 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)
e.POST("/api/post-full-name", api.PostFullName)
// Start the Echo server
e.Logger.Fatal(e.Start(":1323"))
}
Test the new endpoint using curl
Run the Echo server as send a POST request using curl.
curl http://localhost:1323/api/post-full-name -H "Content-Type: application/json" -d '{ "first_name": "Kit", "last_name": "Yuen" }'
Here is the example result.
Add an HTML form
The POST request endpoint is ready and now we could add an HTML form and complete the whole setup. Let's add the form in the about page.
view/about.html
{{define "title"}}
Boatswain Blog | {{index . "name"}}
{{end}}
{{define "body"}}
<h1>{{index . "msg"}}</h1>
<h2>This is the about page.</h2>
<!-- HTML form -->
<form id="post-full-name-form">
<input type="text" id="first-name" placeholder="First Name">
<input type="text" id="last-name" placeholder="Last Name">
<button type="button" id="submit-btn">Submit</button>
</form>
<!-- Print the response after the jQuery ajax request -->
<pre id="form-result"></pre>
<script type="text/javascript">
// Send a ajax request when the submit button is clicked
$("#submit-btn").on("click", function(){
var firstName = $("#first-name").val();
var lastName = $("#last-name").val();
$.ajax({
type: "POST",
url: "/api/post-full-name",
data: JSON.stringify({
first_name: firstName,
last_name: lastName
}),
processData: false,
contentType: "application/json",
dataType: "json"
}).done(
function(data){
$("#form-result").text(JSON.stringify(data, null, 2));
}
).fail(
function(data){
$("#form-result").text("POST request failed!");
}
)
});
</script>
{{end}}
As the form submission required jQuery, let's include it in the view/base.html.
view/base.html
{{define "base.html"}}
<!DOCTYPE html>
<html>
<head>
<title>{{template "title" .}}</title>
<!-- jQuery -->
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
</head>
<body>
{{template "body" .}}
</body>
</html>
{{end}}
Test the HTML form in the about page
Start the Echo server and browse the about page. Fill in the first and last name and then click the submit button. It should show the response JSON as follow.
The project structure
Here is our new project structure. (The project is renamed to handling-http-request-in-go-echo-example-2, 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-2/
├── api/ # folder of api endpoints
│ ├── get_full_name.go # api for get full name
│ ├── post_full_name.go # api for post 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 is the second episode of Handling HTTP request in Go Echo framework (1) and we have added the following:
- Setup a POST request endpoint in the Echo framework.
- Prettify the JSON byte array
- Add an HTML form and bind it to the new POST request using AJAX in jQuery/javascript.
The complete example could be found on gitlab.com.
Posted on April 18, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
September 27, 2024