go-goyave / goyave

🍐 The enterprise REST API framework
https://goyave.dev
MIT License
1.61k stars 67 forks source link

JSON Schema Validator #111

Open snadrus opened 4 years ago

snadrus commented 4 years ago

Other than your input validator, consider the JSON Schema validator (jsonschema.org). Although similar, it has the advantage of write-once, run anywhere. The same validation schema could run on the browser before bothering the server. There would be no challenge keeping the two in synchronization: just use the same validator file.

System-Glitch commented 4 years ago

Hello, can you write a more in-depth description of how you pictured it would work? How would it be used, with examples, etc. Would it be a middleware? Would it be something detached from the current validation system or an extension of it?

snadrus commented 4 years ago

Today (from example):

var (
    StoreRequest validation.RuleSet = validation.RuleSet{
        "name":  {"required", "string", "between:3,50"},
        "price": {"required", "numeric", "min:0.01"},
        "image": {"nullable", "file", "image", "max:2048", "count:1"},
    }

    // ...
)
func Routes(router *goyave.Router) {
   router.Post("/product", product.Store).Validate(product.StoreRequest)
}

With a schema validator:

var (
    StoreRequest = ` 
{
 "$id": "https://example.com/productPost.schema.json", 
 "$schema": "http://json-schema.org/draft-07/schema#",
 "title": "ProductPost", 
 "type": "object", 
 "required": [ "name", "price" ],
 "properties": {
   "name": {
      "type": "string", 
      "minimum": 3, 
      "maximum": 50
   },
   "price": {
      "type": "number",
      "minimum": 0.01
   },
   "image": {
      "type": "string", 
      "maximum": 2048,
   }
 }
}`
)
func Routes(router *goyave.Router) {
    // Uses the Go JSON schema validator:
   router.Post("/product", product.Store).ValidateWithJSONSchema(StoreRequest)

   // So the browser can run the Javascript version of the JSON schema validator too:
   router.Get("/productPost.schema.json", func(response *goyave.Response, request *goyave.Request){
      response.String(http.StatusOK, StoreRequest)
   })
}

The validators immediately tell the user what went wrong in the browser before the form posts to the user. It saves the user from waiting for a POST to process before finding out there's an error. The dev work is similar since the validators produce an error message like "name too long, max 50". To use, a Front-End dev only needs to: