Ensures user input is valid.
api-go
|
|-------> internal
|------> dto
| |-----> websites.go
|
|------> handlers
| |-----> websites.go
|
|------> routes
|-----> websites.go
DTO is used for moving data between client <-> server
Data Transfer Object ( DTO ) : struct whose job is to describe data coming IN or going OUT of your system
DTO defines:
internal/dto/websites.go
package dto
type CreateWebsiteRequest struct {
URL string `json:"url" binding:"required,url,max=2048"`
}
CreateWebsite handler to add logic for validating user’s inputpackage handlers
import (
"net/http"
"github.com/RitikaxG/runState/apps/api-go/internal/dto"
"github.com/gin-gonic/gin"
)
// Handler Fn
func GetWebsites(c *gin.Context) { // gin.Context : single HTTP request + response ( lives only during that request )
c.JSON(http.StatusOK, gin.H{
"message": "List all websites",
})
}
func CreateWebsite(c *gin.Context) {
var body dto.CreateWebsiteRequest // Declaring a Go struct that defines what JSON you expect
// & body : pointer to where body lives in memory
// &body is passed because Gin must modify body, and Go can only modify a variable if you give it its memory address.
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"message": "invalid request body",
"error": err.Error(),
})
return // Prevents handler from continuing
}
c.JSON(http.StatusCreated, gin.H{
"message": "Website successfully created",
"url": body.URL, // Uses parsed data
})
}
Go automatically :
if err := c.ShouldBindJSON(&body); err != nil
What happens here internally ?
Gin:
If anything fails, err != nil.
Examples of failure:
BadRequest status codeinternal/handler/websites.go
internal/routes/websites.go
func RegisterWebsitesRouter(r *gin.RouterGroup) { // gin.RouterGroup : organises the routes
websites := r.Group("/websites")
websites.GET("/", handlers.GetWebsites)
websites.POST("/", handlers.CreateWebsite)
}
When you call: