mirror of
https://github.com/oarkflow/mq.git
synced 2025-10-05 16:06:55 +08:00
feat: update
This commit is contained in:
@@ -3,24 +3,7 @@
|
||||
{
|
||||
"route_uri": "/test-route",
|
||||
"route_method": "POST",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"description": "users",
|
||||
"required": [ "user_id" ],
|
||||
"properties": {
|
||||
"last_name": {
|
||||
"type": "string",
|
||||
"default": "'Baniya'"
|
||||
},
|
||||
"user_id": {
|
||||
"type": [
|
||||
"integer",
|
||||
"string"
|
||||
],
|
||||
"maxLength": 64
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema_file": "test-route.json",
|
||||
"description": "Handle test route",
|
||||
"model": "test_route",
|
||||
"operation": "custom",
|
||||
|
18
services/examples/config/policies/schemas/test-route.json
Normal file
18
services/examples/config/policies/schemas/test-route.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"type": "object",
|
||||
"description": "users",
|
||||
"required": [ "user_id" ],
|
||||
"properties": {
|
||||
"last_name": {
|
||||
"type": "string",
|
||||
"default": "now()"
|
||||
},
|
||||
"user_id": {
|
||||
"type": [
|
||||
"integer",
|
||||
"string"
|
||||
],
|
||||
"maxLength": 64
|
||||
}
|
||||
}
|
||||
}
|
@@ -29,6 +29,10 @@ type Loader struct {
|
||||
UserConfig *UserConfig
|
||||
}
|
||||
|
||||
var JsonSchemaFunctions = map[string]jsonschema.DefaultFunc{
|
||||
"now": jsonschema.DefaultNowFunc,
|
||||
}
|
||||
|
||||
func NewLoader(path string, configFiles ...string) *Loader {
|
||||
var configFile string
|
||||
if len(configFiles) > 0 {
|
||||
@@ -230,6 +234,9 @@ func readSchemas(path string, cfg *UserConfig) error {
|
||||
return err
|
||||
}
|
||||
compiler := jsonschema.NewCompiler()
|
||||
for name, fn := range JsonSchemaFunctions {
|
||||
compiler.RegisterDefaultFunc(name, fn)
|
||||
}
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() && isSupportedExt(filepath.Ext(entry.Name())) {
|
||||
file := filepath.Join(path, entry.Name())
|
||||
@@ -415,6 +422,10 @@ func readApis(path string, cfg *UserConfig) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
compiler := jsonschema.NewCompiler()
|
||||
for name, fn := range JsonSchemaFunctions {
|
||||
compiler.RegisterDefaultFunc(name, fn)
|
||||
}
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() && isSupportedExt(filepath.Ext(entry.Name())) {
|
||||
file := filepath.Join(modelsPath, entry.Name())
|
||||
@@ -428,6 +439,22 @@ func readApis(path string, cfg *UserConfig) error {
|
||||
return err
|
||||
}
|
||||
for i, route := range api.Routes {
|
||||
if len(route.Schema) > 0 {
|
||||
schema, err := compiler.Compile(route.Schema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if schema == nil {
|
||||
return errors.New("compiled schema is nil for route: " + route.Uri)
|
||||
}
|
||||
route.schema = schema
|
||||
} else if route.SchemaFile != "" {
|
||||
schema := cfg.GetSchemaInstance(route.SchemaFile)
|
||||
if schema == nil {
|
||||
return errors.New("schema not found for route: " + route.Uri + ", file: " + route.SchemaFile)
|
||||
}
|
||||
route.schema = schema.Instance
|
||||
}
|
||||
if route.HandlerKey != "" {
|
||||
if handler := cfg.GetHandler(route.HandlerKey); handler != nil {
|
||||
route.Handler = *handler
|
||||
|
@@ -3,8 +3,8 @@ package middlewares
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/oarkflow/json"
|
||||
"github.com/oarkflow/jsonschema"
|
||||
"github.com/oarkflow/jsonschema/request"
|
||||
"github.com/oarkflow/mq/services/utils"
|
||||
)
|
||||
|
||||
var ServerApp *fiber.App
|
||||
@@ -80,17 +80,7 @@ func MatchRouterPath(method, path string) (fiber.Route, bool, map[string]string)
|
||||
}
|
||||
|
||||
// ValidateRequestBySchema - validates each request that has schema validation
|
||||
func ValidateRequestBySchema(c *fiber.Ctx) error {
|
||||
route, matched, _ := MatchRouterPath(c.Method(), c.Path())
|
||||
if !matched {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
key := route.Method + ":" + route.Path
|
||||
schema, exists := utils.GetSchema(key)
|
||||
if !exists {
|
||||
return c.Next()
|
||||
}
|
||||
func ValidateRequestBySchema(schema *jsonschema.Schema, c *fiber.Ctx) error {
|
||||
body := c.Body()
|
||||
if len(body) == 0 {
|
||||
return c.Next()
|
||||
|
@@ -17,15 +17,15 @@ import (
|
||||
"github.com/oarkflow/filters"
|
||||
"github.com/oarkflow/form"
|
||||
"github.com/oarkflow/json"
|
||||
v2 "github.com/oarkflow/jsonschema"
|
||||
"github.com/oarkflow/log"
|
||||
"github.com/oarkflow/protocol/utils/str"
|
||||
|
||||
"github.com/oarkflow/mq"
|
||||
"github.com/oarkflow/mq/consts"
|
||||
"github.com/oarkflow/mq/dag"
|
||||
"github.com/oarkflow/mq/services/http/responses"
|
||||
"github.com/oarkflow/mq/services/middlewares"
|
||||
"github.com/oarkflow/mq/services/utils"
|
||||
"github.com/oarkflow/protocol/utils/str"
|
||||
)
|
||||
|
||||
var ValidationInstance Validation
|
||||
@@ -341,21 +341,19 @@ func prepareHeader(ctx *fiber.Ctx, route *Route) (map[string]any, map[string]any
|
||||
header := make(map[string]any)
|
||||
param := make(map[string]any)
|
||||
query := make(map[string]any)
|
||||
if route.Schema != nil {
|
||||
schema := route.GetSchema()
|
||||
if schema != nil {
|
||||
if schema.Properties != nil {
|
||||
for key, property := range *schema.Properties {
|
||||
if property.In != nil {
|
||||
for _, in := range property.In {
|
||||
switch in {
|
||||
case "param":
|
||||
param[key] = ctx.Params(key)
|
||||
case "query":
|
||||
query[key] = ctx.Query(key)
|
||||
case "body":
|
||||
requiredBody[key] = true
|
||||
}
|
||||
schema := route.GetSchema()
|
||||
if schema != nil {
|
||||
if schema.Properties != nil {
|
||||
for key, property := range *schema.Properties {
|
||||
if property.In != nil {
|
||||
for _, in := range property.In {
|
||||
switch in {
|
||||
case "param":
|
||||
param[key] = ctx.Params(key)
|
||||
case "query":
|
||||
query[key] = ctx.Query(key)
|
||||
case "body":
|
||||
requiredBody[key] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,18 +444,9 @@ func ruleMiddleware(rules map[string]string) fiber.Handler {
|
||||
// requestMiddleware validates the request body in the original form of byte array
|
||||
// against the provided request JSON schema to ensure that the request body is valid.
|
||||
func requestMiddleware(prefix string, route *Route) fiber.Handler {
|
||||
path := CleanAndMergePaths(prefix, route.Uri)
|
||||
var schema *v2.Schema
|
||||
var err error
|
||||
if route.Schema != nil {
|
||||
schema, err = utils.CompileSchema(path, strings.ToUpper(route.Method), route.Schema)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
route.SetSchema(schema)
|
||||
}
|
||||
return func(ctx *fiber.Ctx) error {
|
||||
if route.Schema == nil {
|
||||
schema := route.GetSchema()
|
||||
if schema == nil {
|
||||
return ctx.Next()
|
||||
}
|
||||
requestSchema := ctx.Query("request-schema")
|
||||
@@ -480,11 +469,11 @@ func requestMiddleware(prefix string, route *Route) fiber.Handler {
|
||||
break
|
||||
}
|
||||
}
|
||||
form, _ := ctx.MultipartForm()
|
||||
if form != nil {
|
||||
multipartForm, _ := ctx.MultipartForm()
|
||||
if multipartForm != nil {
|
||||
return ctx.Next()
|
||||
}
|
||||
return middlewares.ValidateRequestBySchema(ctx)
|
||||
return middlewares.ValidateRequestBySchema(schema, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -188,14 +188,13 @@ type RestrictedFields struct {
|
||||
}
|
||||
|
||||
type Route struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Description string `json:"description" yaml:"description"`
|
||||
Uri string `json:"route_uri" yaml:"route_uri"`
|
||||
HandlerKey string `json:"handler_key" yaml:"handler_key"`
|
||||
Method string `json:"route_method" yaml:"route_method"`
|
||||
Schema []byte `json:"schema" yaml:"schema"`
|
||||
SchemaFile string `json:"schema_file" yaml:"schema_file"`
|
||||
schema *v2.Schema
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Description string `json:"description" yaml:"description"`
|
||||
Uri string `json:"route_uri" yaml:"route_uri"`
|
||||
HandlerKey string `json:"handler_key" yaml:"handler_key"`
|
||||
Method string `json:"route_method" yaml:"route_method"`
|
||||
Schema []byte `json:"schema" yaml:"schema"`
|
||||
SchemaFile string `json:"schema_file" yaml:"schema_file"`
|
||||
Rules map[string]string `json:"rules" yaml:"rules"`
|
||||
CustomRules []string `json:"custom_rules" yaml:"custom_rules"`
|
||||
Model string `json:"model" yaml:"model"`
|
||||
@@ -203,6 +202,7 @@ type Route struct {
|
||||
Middlewares []Middleware `json:"middlewares" yaml:"middlewares"`
|
||||
Operation string `json:"operation" yaml:"operation"`
|
||||
RestrictedFields RestrictedFields `json:"restricted_fields" yaml:"restricted_fields"`
|
||||
schema *v2.Schema
|
||||
}
|
||||
|
||||
func (r *Route) GetSchema() *v2.Schema {
|
||||
|
Reference in New Issue
Block a user