Skip to content

Instantly share code, notes, and snippets.

@byyam
Last active September 6, 2021 11:28
Show Gist options
  • Save byyam/34db36d6cc055a5b33eb72a5070c39a5 to your computer and use it in GitHub Desktop.
Save byyam/34db36d6cc055a5b33eb72a5070c39a5 to your computer and use it in GitHub Desktop.
gin json schema
package main
import (
"fmt"
"bytes"
"strings"
"io/ioutil"
"net/http"
"github.com/gin-gonic/gin"
"github.com/xeipuuv/gojsonschema"
)
const RequestSchema = `{
"definitions": {},
"$schema": "",
"type": "object",
"required": [
"req_id"
],
"properties": {
"req_id": {
"$id": "#/properties/req_id",
"type": "string",
"minLength": 1,
"maxLength": 6
}
}
}`
func CheckDocumentValidate(documentString string, schemaString string) (bool, string) {
schemaLoader := gojsonschema.NewStringLoader(schemaString)
s, err := gojsonschema.NewSchema(schemaLoader)
if err != nil {
return false, err.Error()
}
result, err := s.Validate(gojsonschema.NewStringLoader(documentString))
if err != nil {
return false, err.Error()
}
if !result.Valid() {
var errors []string
for _, er := range result.Errors() {
errors = append(errors, er.String())
}
return false, strings.Join(errors, "|")
}
return true, ""
}
func middleware(schemaStr string) gin.HandlerFunc {
return func(c *gin.Context) {
var bodyBytes []byte
if c.Request.Body != nil {
bodyBytes, _ = ioutil.ReadAll(c.Request.Body)
}
// Restore the io.ReadCloser to its original state
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
fmt.Printf("%s \n", string(bodyBytes))
if ok, errmsg := CheckDocumentValidate(string(bodyBytes), schemaStr); !ok {
c.JSON(http.StatusForbidden, gin.H{"error": errmsg})
c.Abort()
return
}
fmt.Println("I am a middleware for json schema validation")
c.Next()
}
}
func middleware1(c *gin.Context) {
var bodyBytes []byte
if c.Request.Body != nil {
bodyBytes, _ = ioutil.ReadAll(c.Request.Body)
}
// Restore the io.ReadCloser to its original state
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
fmt.Printf("%s \n", string(bodyBytes))
fmt.Println("I am a middleware1 for json schema validation")
c.Next()
}
type EmailReq struct {
Email string
Password string
}
func test(c *gin.Context) {
//data := &E{}
//c.Bind(data)
//fmt.Println(data) //prints empty as json body is already used
var emailReq EmailReq
if err := c.ShouldBindJSON(&emailReq); err != nil {
c.JSON(http.StatusForbidden, gin.H{"error": err})
return
}
fmt.Printf("body is: %+v \n", emailReq)
c.JSON(http.StatusOK, "pon")
}
func main() {
router := gin.Default()
//router.Use(middleware())
router.POST("/test", middleware(RequestSchema), test)
//Listen and serve
router.Run("127.0.0.1:13000")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment