repo_description: KrakenD Community Edition: High-performance, stateless, declarative, API Gateway written in Go.
repo_topics: ai-gateway api-gateway apis async backend-services cloud-native docker go golang graphql microservice microservices nats reverse-proxy
code: package krakend
  
  import (
  	"encoding/json"
  
  	"github.com/gin-gonic/gin"
  
  	botdetector "github.com/krakend/krakend-botdetector/v2/gin"
  	httpsecure "github.com/krakend/krakend-httpsecure/v2/gin"
  	lua "github.com/krakend/krakend-lua/v2/router/gin"
  	opencensus "github.com/krakend/krakend-opencensus/v2/router/gin"
  	"github.com/luraproject/lura/v2/config"
  	"github.com/luraproject/lura/v2/core"
  	luragin "github.com/luraproject/lura/v2/router/gin"
  	"github.com/luraproject/lura/v2/transport/http/server"
  )
  
  // NewEngine creates a new gin engine with some default values and a secure middleware
  func NewEngine(cfg config.ServiceConfig, opt luragin.EngineOptions) *gin.Engine {
  	engine := luragin.NewEngine(cfg, opt)
  
  	engine.NoRoute(opencensus.HandlerFunc(&config.EndpointConfig{Endpoint: "NoRoute"}, defaultHandler, nil))
  	engine.NoMethod(opencensus.HandlerFunc(&config.EndpointConfig{Endpoint: "NoMethod"}, defaultHandler, nil))
  	if v, ok := cfg.ExtraConfig[luragin.Namespace]; ok && v != nil {
  		var ginOpts ginOptions
  		if b, err := json.Marshal(v); err == nil {
  			json.Unmarshal(b, &ginOpts)
  		}
  		if ginOpts.ErrorBody.Err404 != nil {
  			engine.NoRoute(opencensus.HandlerFunc(&config.EndpointConfig{Endpoint: "NoRoute"}, jsonHandler(404, ginOpts.ErrorBody.Err404), nil))
  		}
  		if ginOpts.ErrorBody.Err405 != nil {
  			engine.NoMethod(opencensus.HandlerFunc(&config.EndpointConfig{Endpoint: "NoMethod"}, jsonHandler(405, ginOpts.ErrorBody.Err405), nil))
  		}
  	}
  
  	logPrefix := "[SERVICE: Gin]"
  	if err := httpsecure.Register(cfg.ExtraConfig, engine); err != nil && err != httpsecure.ErrNoConfig {
  		opt.Logger.Warning(logPrefix+"[HTTPsecure]", err)
  	} else if err == nil {
  		opt.Logger.Debug(logPrefix + "[HTTPsecure] Successfully loaded module")
  	}
  
  	lua.Register(opt.Logger, cfg.ExtraConfig, engine)
  
  	botdetector.Register(cfg, opt.Logger, engine)
  
  	return engine
  }
  
  func defaultHandler(c *gin.Context) {
  	c.Header(core.KrakendHeaderName, core.KrakendHeaderValue)
  	c.Header(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue)
  }
  
  func jsonHandler(status int, v interface{}) gin.HandlerFunc {
  	return func(c *gin.Context) {
  		defaultHandler(c)
  		c.JSON(status, v)
  	}
  }
  
  type engineFactory struct{}
  
  func (engineFactory) NewEngine(cfg config.ServiceConfig, opt luragin.EngineOptions) *gin.Engine {
  	return NewEngine(cfg, opt)
  }
  
  type ginOptions struct {
  	// ErrorBody sets the json body to return to handlers like NoRoute (404) and NoMethod (405)
  	// Example: "404": { "error": "Not Found", "status": 404 }
  	ErrorBody struct {
  		Err404 interface{} `json:"404"`
  		Err405 interface{} `json:"405"`
  	} `json:"error_body"`
  }
  