In this chapter, we’ll improve upon our previous example by introducing structured data handling to eliminate hardcoded parameter names.

Request Structure

Let’s define a structure to handle client parameters:

  1. type HelloReq struct {
  2. Name string // User's name
  3. Age int // User's age
  4. }

This approach allows us to document our parameters and specify their types explicitly, eliminating the need for hardcoded parameter names.

Implementation

Here’s our updated web server implementation:

main.go

  1. package main
  2. import (
  3. "github.com/gogf/gf/v2/frame/g"
  4. "github.com/gogf/gf/v2/net/ghttp"
  5. )
  6. type HelloReq struct {
  7. Name string // User's name
  8. Age int // User's age
  9. }
  10. func main() {
  11. s := g.Server()
  12. s.BindHandler("/", func(r *ghttp.Request) {
  13. var req HelloReq
  14. if err := r.Parse(&req); err != nil {
  15. r.Response.Write(err.Error())
  16. return
  17. }
  18. if req.Name == "" {
  19. r.Response.Write("name should not be empty")
  20. return
  21. }
  22. if req.Age <= 0 {
  23. r.Response.Write("invalid age value")
  24. return
  25. }
  26. r.Response.Writef(
  27. "Hello %s! Your Age is %d",
  28. req.Name,
  29. req.Age,
  30. )
  31. })
  32. s.SetPort(8000)
  33. s.Run()
  34. }

Key improvements in this version:

  • We use r.Parse to automatically map request parameters to our struct. This method handles the parameter parsing and assignment based on predefined mapping rules (which we’ll cover in detail in the type conversion documentation).
  • We’ve added input validation to ensure both Name and Age parameters contain valid values.

Testing the API

When we visit http://127.0.0.1:8000/?name=john&age=18, we get the expected response:

img.png

Let’s test the validation by making a request without parameters to http://127.0.0.1:8000/:

img_2.png

Room for Improvement

While we’ve made progress by using structured data, there are still several areas we can enhance:

  • The r.Parse operation is boilerplate code that should be separated from our business logic
  • Having to call r.Parse in every API handler becomes repetitive
  • The manual validation using multiple if statements can become unwieldy as the number of parameters grows

Can we make this code more elegant and maintainable? Absolutely! In the next chapter, we’ll explore a more streamlined approach to handle these concerns.