Categorygithub.com/rookie-ninja/rk-mux
repository
1.2.18
Repository: https://github.com/rookie-ninja/rk-mux.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author
No description provided by the author

# README

rk-mux

build codecov Go Report Card License

Middlewares & bootstrapper designed for gorilla/mux web framework. Documentation.

This belongs to rk-boot family.

image

Architecture

image

Supported bootstrap

BootstrapDescription
YAML basedStart gorilla/mux microservice from YAML
Code basedStart gorilla/mux microservice from code

Supported instances

All instances could be configured via YAML or Code.

User can enable anyone of those as needed! No mandatory binding!

InstanceDescription
mux.RouterCompatible with original gorilla/mux service functionalities
ConfigConfigure spf13/viper as config instance and reference it from YAML
LoggerConfigure uber-go/zap logger configuration and reference it from YAML
EventConfigure logging of RPC with rk-query and reference it from YAML
CertFetch TLS/SSL certificates start microservice.
PrometheusStart prometheus client at client side and push metrics to pushgateway as needed.
SwaggerBuiltin swagger UI handler.
DocsBuiltin RapiDoc instance which can be used to replace swagger and RK TV.
CommonServiceList of common APIs.
StaticFileHandlerA Web UI shows files could be downloaded from server, currently support source of local and embed.FS.
PProfPProf web UI.

Supported middlewares

All middlewares could be configured via YAML or Code.

User can enable anyone of those as needed! No mandatory binding!

MiddlewareDescription
PromCollect RPC metrics and export to prometheus client.
LoggingLog every RPC requests as event with rk-query.
TraceCollect RPC trace and export it to stdout, file or jaeger with open-telemetry/opentelemetry-go.
PanicRecover from panic for RPC requests and log it.
MetaSend micsro service metadata as header to client.
AuthSupport [Basic Auth] and [API Key] authorization types.
RateLimitLimiting RPC rate globally or per path.
CORSServer side CORS validation.
JWTServer side JWT validation.
SecureServer side secure validation.
CSRFServer side csrf validation.

Installation

go get github.com/rookie-ninja/rk-mux

Quick Start

In the bellow example, we will start microservice with bellow functionality and middlewares enabled via YAML.

  • Http server with gorilla/mux router
  • Swagger UI
  • Docs
  • CommonService
  • Prometheus Metrics (middleware)
  • Logging (middleware)
  • Meta (middleware)

Please refer example at example/boot/simple.

1.Create boot.yaml

---
mux:
  - name: greeter                     # Required
    port: 8080                        # Required
    enabled: true                     # Required
    commonService:                    # Optional
      enabled: true                   # Optional, default: false
    sw:                               # Optional
      enabled: true                   # Optional, default: false
    docs:                             # Optional
      enabled: true                   # Optional, default: false
    prom:
      enabled: true                   # Optional, default: false
    middleware:
      logging:
        enabled: true
      prom:
        enabled: true
      meta:
        enabled: true

2.Create main.go

// Copyright (c) 2021 rookie-ninja
//
// Use of this source code is governed by an Apache-style
// license that can be found in the LICENSE file.
package main

import (
	"context"
	_ "embed"
	"fmt"
	"github.com/rookie-ninja/rk-entry/v2/entry"
	"github.com/rookie-ninja/rk-mux/boot"
	"github.com/rookie-ninja/rk-mux/middleware"
	"net/http"
)

//go:embed boot.yaml
var boot []byte

// @title RK Swagger for Mux
// @version 1.0
// @description This is a greeter service with rk-boot.
func main() {
	// Bootstrap preload entries
	rkentry.BootstrapPreloadEntryYAML(boot)

	// Bootstrap gin entry from boot config
	res := rkmux.RegisterMuxEntryYAML(boot)

	// Get MuxEntry
	muxEntry := res["greeter"].(*rkmux.MuxEntry)
	// Use *mux.Router adding handler.
	muxEntry.Router.NewRoute().Path("/v1/greeter").HandlerFunc(Greeter)

	// Bootstrap mux entry
	muxEntry.Bootstrap(context.Background())

	// Wait for shutdown signal
	rkentry.GlobalAppCtx.WaitForShutdownSig()

	// Interrupt mux entry
	muxEntry.Interrupt(context.Background())
}

// Greeter handler
// @Summary Greeter service
// @Id 1
// @version 1.0
// @produce application/json
// @Param name query string true "Input name"
// @Success 200 {object} GreeterResponse
// @Router /v1/greeter [get]
func Greeter(writer http.ResponseWriter, req *http.Request) {
	rkmuxmid.WriteJson(writer, http.StatusOK, &GreeterResponse{
		Message: fmt.Sprintf("Hello %s!", req.URL.Query().Get("name")),
	})
}

// Response.
type GreeterResponse struct {
	Message string
}

3.Start server

$ go run main.go

4.Validation

4.1 Http server with mux.Router

Try to test mux.Router with curl

# Curl to common service
$ curl localhost:8080/rk/v1/ready
{
  "ready": true
}

$ curl localhost:8080/rk/v1/alive
{
  "alive": true
}

4.2 Swagger UI

Please refer sw section at Full YAML.

By default, we could access swagger UI at http://localhost:8080/sw

sw

4.3 Docs UI

Please refer docs section at Full YAML.

By default, we could access docs UI at http://localhost:8080/docs

docs

4.4 Prometheus Metrics

Please refer middleware.prom section at Full YAML.

By default, we could access prometheus client at http://localhost:8080/metrics

prom

4.5 Logging

Please refer middleware.logging section at Full YAML.

By default, we enable zap logger and event logger with encoding type of [console]. Encoding type of [json] and [flatten] is also supported.

2021-12-30T03:39:19.060+0800    INFO    boot/mux_entry.go:1048  Bootstrap muxEntry      {"eventId": "611daa72-adc2-442b-8569-0268088750a0", "entryName": "greeter"}
------------------------------------------------------------------------
endTime=2021-12-30T03:39:19.062581+08:00
startTime=2021-12-30T03:39:19.06096+08:00
elapsedNano=1621724
timezone=CST
ids={"eventId":"611daa72-adc2-442b-8569-0268088750a0"}
app={"appName":"rk","appVersion":"","entryName":"greeter","entryType":"MuxEntry"}
env={"arch":"amd64","az":"*","domain":"*","hostname":"lark.local","localIP":"192.168.101.5","os":"darwin","realm":"*","region":"*"}
payloads={"commonServiceEnabled":true,"commonServicePathPrefix":"/rk/v1/","muxPort":8080,"promEnabled":true,"promPath":"/metrics","promPort":8080,"swEnabled":true,"swPath":"/sw/","tvEnabled":true,"tvPath":"/rk/v1/tv/"}
error={}
counters={}
pairs={}
timing={}
remoteAddr=localhost
operation=Bootstrap
resCode=OK
eventStatus=Ended
EOE

4.6 Meta

Please refer meta section at Full YAML.

By default, we will send back some metadata to client including gateway with headers.

$ curl -vs localhost:8080/rk/v1/ready
...
< HTTP/1.1 200 OK
< Content-Type: application/json
< X-Request-Id: bf7aaebd-1cb4-4da6-ac03-8830c34851c7
< X-Rk-App-Name: rk
< X-Rk-App-Unix-Time: 2021-12-30T03:39:46.316021+08:00
< X-Rk-App-Version:
< X-Rk-Received-Time: 2021-12-30T03:39:46.316021+08:00
< Date: Wed, 29 Dec 2021 19:39:46 GMT
...

4.7 Send request

We registered /v1/greeter API in gorilla/mux router and let's validate it!

$ curl -vs "localhost:8080/v1/greeter?name=rk-dev"
*   Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 8080 failed: Connection refused
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /v1/greeter?name=rk-dev HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< X-Request-Id: 3d4a75fd-19ce-411f-967a-d27ccb7dd23e
< X-Rk-App-Name: rk
< X-Rk-App-Unix-Time: 2021-12-30T03:40:32.309171+08:00
< X-Rk-App-Version:
< X-Rk-Received-Time: 2021-12-30T03:40:32.309171+08:00
< Date: Wed, 29 Dec 2021 19:40:32 GMT
< Content-Length: 27
<
* Connection #0 to host localhost left intact
{"Message":"Hello rk-dev!"}

4.8 RPC logs

Bellow logs would be printed in stdout.

------------------------------------------------------------------------
endTime=2021-12-30T03:40:32.309237+08:00
startTime=2021-12-30T03:40:32.309164+08:00
elapsedNano=73246
timezone=CST
ids={"eventId":"3d4a75fd-19ce-411f-967a-d27ccb7dd23e","requestId":"3d4a75fd-19ce-411f-967a-d27ccb7dd23e"}
app={"appName":"rk","appVersion":"","entryName":"greeter","entryType":"MuxEntry"}
env={"arch":"amd64","az":"*","domain":"*","hostname":"lark.local","localIP":"192.168.101.5","os":"darwin","realm":"*","region":"*"}
payloads={"apiMethod":"GET","apiPath":"/v1/greeter","apiProtocol":"HTTP/1.1","apiQuery":"name=rk-dev","userAgent":"curl/7.64.1"}
error={}
counters={}
pairs={}
timing={}
remoteAddr=127.0.0.1:49571
operation=/v1/greeter
resCode=200
eventStatus=Ended
EOE

4.9 RPC prometheus metrics

Prometheus client will automatically register into gorilla/mux instance at /metrics.

Access http://localhost:8080/metrics

image

YAML Options

User can start multiple gorilla/mux instances at the same time. Please make sure use different port and name.

Mux

namedescriptiontypedefault value
mux.nameRequired, The name of mux serverstringN/A
mux.portRequired, The port of mux serverintegernil, server won't start
mux.enabledOptional, Enable mux entry or notboolfalse
mux.descriptionOptional, Description of mux entry.string""
mux.certEntryOptional, Reference of certEntry declared in cert entrystring""
mux.loggerEntryOptional, Reference of loggerEntry declared in LoggerEntrystring""
mux.eventEntryOptional, Reference of eventLEntry declared in eventEntrystring""

CommonService

PathDescription
/rk/v1/gcTrigger GC
/rk/v1/readyGet application readiness status.
/rk/v1/aliveGet application aliveness status.
/rk/v1/infoGet application and process info.
namedescriptiontypedefault value
mux.commonService.enabledOptional, Enable builtin common servicebooleanfalse
mux.commonService.pathPrefixOptional, Provide path prefixstring/rk/v1

Swagger

namedescriptiontypedefault value
mux.sw.enabledOptional, Enable swagger service over gin serverbooleanfalse
mux.sw.pathOptional, The path access swagger service from webstring/sw
mux.sw.jsonPathOptional, Where the swagger.json files are stored locally[]string[""]
mux.sw.headersOptional, Headers would be sent to caller as scheme of [key:value][]string[]

Docs (RapiDoc)

namedescriptiontypedefault value
mux.docs.enabledOptional, Enable RapiDoc service over gin serverbooleanfalse
mux.docs.pathOptional, The path access docs service from webstring/docs
mux.docs.jsonPathOptional, Where the swagger.json or open API files are stored locally[]string[""]
mux.docs.headersOptional, Headers would be sent to caller as scheme of [key:value][]string[]
mux.docs.style.themeOptional, light and dark are supported optionsstring[]
mux.docs.debugOptional, Enable debugging mode in RapiDoc which can be used as the same as Swagger UIbooleanfalse

Prom Client

namedescriptiontypedefault value
mux.prom.enabledOptional, Enable prometheusbooleanfalse
mux.prom.pathOptional, Path of prometheusstring/metrics
mux.prom.pusher.enabledOptional, Enable prometheus pusherboolfalse
mux.prom.pusher.jobNameOptional, Job name would be attached as label while pushing to remote pushgatewaystring""
mux.prom.pusher.remoteAddressOptional, PushGateWay address, could be form of http://x.x.x.x or x.x.x.xstring""
mux.prom.pusher.intervalMsOptional, Push interval in millisecondsstring1000
mux.prom.pusher.basicAuthOptional, Basic auth used to interact with remote pushgateway, form of [user:pass]string""
mux.prom.pusher.certEntryOptional, Reference of rkentry.CertEntrystring""

Static file handler

namedescriptiontypedefault value
mux.static.enabledOptional, Enable static file handlerbooleanfalse
mux.static.pathOptional, path of static file handlerstring/static
mux.static.sourceTypeRequired, local and embed.FS are supportedstring""
mux.static.sourcePathRequired, full path of source directorystring""
  • About embed.FS User has to set embedFS before Bootstrap() function as bellow:
//go:embed /*
var staticFS embed.FS

rkentry.GlobalAppCtx.AddEmbedFS(rkentry.StaticFileHandlerEntryType, "greeter", &staticFS)

Middlewares

namedescriptiontypedefault value
mux.middleware.ignoreThe paths of prefix that will be ignored by middleware[]string[]

Logging

namedescriptiontypedefault value
mux.middleware.logging.enabledEnable log middlewarebooleanfalse
mux.middleware.logging.ignoreThe paths of prefix that will be ignored by middleware[]string[]
mux.middleware.logging.loggerEncodingjson or console or flattenstringconsole
mux.middleware.logging.loggerOutputPathsOutput paths[]stringstdout
mux.middleware.logging.eventEncodingjson or console or flattenstringconsole
mux.middleware.logging.eventOutputPathsOutput paths[]stringfalse

We will log two types of log for every RPC call.

  • Logger

Contains user printed logging with requestId or traceId.

  • Event

Contains per RPC metadata, response information, environment information and etc.

FieldDescription
endTimeAs name described
startTimeAs name described
elapsedNanoElapsed time for RPC in nanoseconds
timezoneAs name described
idsContains three different ids(eventId, requestId and traceId). If meta interceptor was enabled or event.SetRequestId() was called by user, then requestId would be attached. eventId would be the same as requestId if meta interceptor was enabled. If trace interceptor was enabled, then traceId would be attached.
appContains appName, appVersion, entryName, entryType.
envContains arch, az, domain, hostname, localIP, os, realm, region. realm, region, az, domain were retrieved from environment variable named as REALM, REGION, AZ and DOMAIN. "*" means empty environment variable.
payloadsContains RPC related metadata
errorContains errors if occur
countersSet by calling event.SetCounter() by user.
pairsSet by calling event.AddPair() by user.
timingSet by calling event.StartTimer() and event.EndTimer() by user.
remoteAddrAs name described
operationRPC method name
resCodeResponse code of RPC
eventStatusEnded or InProgress
  • example
------------------------------------------------------------------------
endTime=2021-12-30T03:40:32.309237+08:00
startTime=2021-12-30T03:40:32.309164+08:00
elapsedNano=73246
timezone=CST
ids={"eventId":"3d4a75fd-19ce-411f-967a-d27ccb7dd23e","requestId":"3d4a75fd-19ce-411f-967a-d27ccb7dd23e"}
app={"appName":"rk","appVersion":"","entryName":"greeter","entryType":"MuxEntry"}
env={"arch":"amd64","az":"*","domain":"*","hostname":"lark.local","localIP":"192.168.101.5","os":"darwin","realm":"*","region":"*"}
payloads={"apiMethod":"GET","apiPath":"/v1/greeter","apiProtocol":"HTTP/1.1","apiQuery":"name=rk-dev","userAgent":"curl/7.64.1"}
error={}
counters={}
pairs={}
timing={}
remoteAddr=127.0.0.1:49571
operation=/v1/greeter
resCode=200
eventStatus=Ended
EOE

Prometheus

namedescriptiontypedefault value
mux.middleware.prom.enabledEnable metrics middlewarebooleanfalse
mux.middleware.prom.ignoreThe paths of prefix that will be ignored by middleware[]string[]

Auth

Enable the server side auth. codes.Unauthenticated would be returned to client if not authorized with user defined credential.

namedescriptiontypedefault value
mux.middleware.auth.enabledEnable auth middlewarebooleanfalse
mux.middleware.auth.ignoreThe paths of prefix that will be ignored by middleware[]string[]
mux.middleware.auth.basicBasic auth credentials as scheme of user:pass[]string[]
mux.middleware.auth.apiKeyAPI key auth[]string[]

Meta

Send application metadata as header to client.

namedescriptiontypedefault value
mux.middleware.meta.enabledEnable meta middlewarebooleanfalse
mux.middleware.meta.ignoreThe paths of prefix that will be ignored by middleware[]string[]
mux.middleware.meta.prefixHeader key was formed as X--XXXstringRK

Trace

namedescriptiontypedefault value
mux.middleware.trace.enabledEnable tracing middlewarebooleanfalse
mux.middleware.trace.ignoreThe paths of prefix that will be ignored by middleware[]string[]
mux.middleware.trace.exporter.file.enabledEnable file exporterbooleanfalse
mux.middleware.trace.exporter.file.outputPathExport tracing info to filesstringstdout
mux.middleware.trace.exporter.jaeger.agent.enabledExport tracing info to jaeger agentbooleanfalse
mux.middleware.trace.exporter.jaeger.agent.hostAs name describedstringlocalhost
mux.middleware.trace.exporter.jaeger.agent.portAs name describedint6831
mux.middleware.trace.exporter.jaeger.collector.enabledExport tracing info to jaeger collectorbooleanfalse
mux.middleware.trace.exporter.jaeger.collector.endpointAs name describedstringhttp://localhost:16368/api/trace
mux.middleware.trace.exporter.jaeger.collector.usernameAs name describedstring""
mux.middleware.trace.exporter.jaeger.collector.passwordAs name describedstring""

RateLimit

namedescriptiontypedefault value
mux.middleware.rateLimit.enabledEnable rate limit middlewarebooleanfalse
mux.middleware.rateLimit.ignoreThe paths of prefix that will be ignored by middleware[]string[]
mux.middleware.rateLimit.algorithmProvide algorithm, tokenBucket and leakyBucket are available optionsstringtokenBucket
mux.middleware.rateLimit.reqPerSecRequest per second globallyint0
mux.middleware.rateLimit.paths.pathFull pathstring""
mux.middleware.rateLimit.paths.reqPerSecRequest per second by full pathint0

CORS

namedescriptiontypedefault value
mux.middleware.cors.enabledEnable cors middlewarebooleanfalse
mux.middleware.cors.ignoreThe paths of prefix that will be ignored by middleware[]string[]
mux.middleware.cors.allowOriginsProvide allowed origins with wildcard enabled.[]string*
mux.middleware.cors.allowMethodsProvide allowed methods returns as response header of OPTIONS request.[]stringAll http methods
mux.middleware.cors.allowHeadersProvide allowed headers returns as response header of OPTIONS request.[]stringHeaders from request
mux.middleware.cors.allowCredentialsReturns as response header of OPTIONS request.boolfalse
mux.middleware.cors.exposeHeadersProvide exposed headers returns as response header of OPTIONS request.[]string""
mux.middleware.cors.maxAgeProvide max age returns as response header of OPTIONS request.int0

JWT

In order to make swagger UI and RK tv work under JWT without JWT token, we need to ignore prefixes of paths as bellow.

jwt:
  ...
  ignore:
    - "/sw"
namedescriptiontypedefault value
mux.middleware.jwt.enabledOptional, Enable JWT middlewarebooleanfalse
mux.middleware.jwt.ignoreOptional, Provide ignoring path prefix.[]string[]
mux.middleware.jwt.signerEntryOptional, Provide signerEntry name.string""
mux.middleware.jwt.symmetric.algorithmRequired if symmetric specified. One of HS256, HS384, HS512string""
mux.middleware.jwt.symmetric.tokenOptional, raw token for signing and verificationstring""
mux.middleware.jwt.symmetric.tokenPathOptional, path of token filestring""
mux.middleware.jwt.asymmetric.algorithmRequired if symmetric specified. One of RS256, RS384, RS512, ES256, ES384, ES512string""
mux.middleware.jwt.asymmetric.privateKeyOptional, raw private key file for signingstring""
mux.middleware.jwt.asymmetric.privateKeyPathOptional, private key file path for signingstring""
mux.middleware.jwt.asymmetric.publicKeyOptional, raw public key file for verificationstring""
mux.middleware.jwt.asymmetric.publicKeyPathOptional, public key file path for verificationstring""
mux.middleware.jwt.tokenLookupProvide token lookup scheme, please see bellow description.string"header:Authorization"
mux.middleware.jwt.authSchemeProvide auth scheme.stringBearer

The supported scheme of tokenLookup

// Optional. Default value "header:Authorization".
// Possible values:
// - "header:<name>"
// - "query:<name>"
// Multiply sources example:
// - "header: Authorization,cookie: myowncookie"

Secure

namedescriptiontypedefault value
mux.middleware.secure.enabledEnable secure middlewarebooleanfalse
mux.middleware.secure.ignoreIgnoring path prefix.[]string[]
mux.middleware.secure.xssProtectionX-XSS-Protection header value.string"1; mode=block"
mux.middleware.secure.contentTypeNosniffX-Content-Type-Options header value.stringnosniff
mux.middleware.secure.xFrameOptionsX-Frame-Options header value.stringSAMEORIGIN
mux.middleware.secure.hstsMaxAgeStrict-Transport-Security header value.int0
mux.middleware.secure.hstsExcludeSubdomainsExcluding subdomains of HSTS.boolfalse
mux.middleware.secure.hstsPreloadEnabledEnabling HSTS preload.boolfalse
mux.middleware.secure.contentSecurityPolicyContent-Security-Policy header value.string""
mux.middleware.secure.cspReportOnlyContent-Security-Policy-Report-Only header value.boolfalse
mux.middleware.secure.referrerPolicyReferrer-Policy header value.string""

CSRF

namedescriptiontypedefault value
mux.middleware.csrf.enabledEnable csrf middlewarebooleanfalse
mux.middleware.csrf.ignoreIgnoring path prefix.[]string[]
mux.middleware.csrf.tokenLengthProvide the length of the generated token.int32
mux.middleware.csrf.tokenLookupProvide csrf token lookup rules, please see code comments for details.string"header:X-CSRF-Token"
mux.middleware.csrf.cookieNameProvide name of the CSRF cookie. This cookie will store CSRF token.string_csrf
mux.middleware.csrf.cookieDomainDomain of the CSRF cookie.string""
mux.middleware.csrf.cookiePathPath of the CSRF cookie.string""
mux.middleware.csrf.cookieMaxAgeProvide max age (in seconds) of the CSRF cookie.int86400
mux.middleware.csrf.cookieHttpOnlyIndicates if CSRF cookie is HTTP only.boolfalse
mux.middleware.csrf.cookieSameSiteIndicates SameSite mode of the CSRF cookie. Options: lax, strict, none, defaultstringdefault

Full YAML

---
#app:
#  name: my-app                                            # Optional, default: "rk-app"
#  version: "v1.0.0"                                       # Optional, default: "v0.0.0"
#  description: "this is description"                      # Optional, default: ""
#  keywords: ["rk", "golang"]                              # Optional, default: []
#  homeUrl: "http://example.com"                           # Optional, default: ""
#  docsUrl: ["http://example.com"]                         # Optional, default: []
#  maintainers: ["rk-dev"]                                 # Optional, default: []
#logger:
#  - name: my-logger                                       # Required
#    description: "Description of entry"                   # Optional
#    domain: "*"                                           # Optional, default: "*"
#    default: false                                        # Optional, default: false, use as default logger entry
#    zap:                                                  # Optional
#      level: info                                         # Optional, default: info
#      development: true                                   # Optional, default: true
#      disableCaller: false                                # Optional, default: false
#      disableStacktrace: true                             # Optional, default: true
#      encoding: console                                   # Optional, default: console
#      outputPaths: ["stdout"]                             # Optional, default: [stdout]
#      errorOutputPaths: ["stderr"]                        # Optional, default: [stderr]
#      encoderConfig:                                      # Optional
#        timeKey: "ts"                                     # Optional, default: ts
#        levelKey: "level"                                 # Optional, default: level
#        nameKey: "logger"                                 # Optional, default: logger
#        callerKey: "caller"                               # Optional, default: caller
#        messageKey: "msg"                                 # Optional, default: msg
#        stacktraceKey: "stacktrace"                       # Optional, default: stacktrace
#        skipLineEnding: false                             # Optional, default: false
#        lineEnding: "\n"                                  # Optional, default: \n
#        consoleSeparator: "\t"                            # Optional, default: \t
#      sampling:                                           # Optional, default: nil
#        initial: 0                                        # Optional, default: 0
#        thereafter: 0                                     # Optional, default: 0
#      initialFields:                                      # Optional, default: empty map
#        key: value
#    lumberjack:                                           # Optional, default: nil
#      filename:
#      maxsize: 1024                                       # Optional, suggested: 1024 (MB)
#      maxage: 7                                           # Optional, suggested: 7 (day)
#      maxbackups: 3                                       # Optional, suggested: 3 (day)
#      localtime: true                                     # Optional, suggested: true
#      compress: true                                      # Optional, suggested: true
#    loki:
#      enabled: true                                       # Optional, default: false
#      addr: localhost:3100                                # Optional, default: localhost:3100
#      path: /loki/api/v1/push                             # Optional, default: /loki/api/v1/push
#      username: ""                                        # Optional, default: ""
#      password: ""                                        # Optional, default: ""
#      maxBatchWaitMs: 3000                                # Optional, default: 3000
#      maxBatchSize: 1000                                  # Optional, default: 1000
#      insecureSkipVerify: false                           # Optional, default: false
#      labels:                                             # Optional, default: empty map
#        my_label_key: my_label_value
#event:
#  - name: my-event                                        # Required
#    description: "Description of entry"                   # Optional
#    domain: "*"                                           # Optional, default: "*"
#    default: false                                        # Optional, default: false, use as default event entry
#    encoding: console                                     # Optional, default: console
#    outputPaths: ["stdout"]                               # Optional, default: [stdout]
#    lumberjack:                                           # Optional, default: nil
#      filename:
#      maxsize: 1024                                       # Optional, suggested: 1024 (MB)
#      maxage: 7                                           # Optional, suggested: 7 (day)
#      maxbackups: 3                                       # Optional, suggested: 3 (day)
#      localtime: true                                     # Optional, suggested: true
#      compress: true                                      # Optional, suggested: true
#    loki:
#      enabled: true                                       # Optional, default: false
#      addr: localhost:3100                                # Optional, default: localhost:3100
#      path: /loki/api/v1/push                             # Optional, default: /loki/api/v1/push
#      username: ""                                        # Optional, default: ""
#      password: ""                                        # Optional, default: ""
#      maxBatchWaitMs: 3000                                # Optional, default: 3000
#      maxBatchSize: 1000                                  # Optional, default: 1000
#      insecureSkipVerify: false                           # Optional, default: false
#      labels:                                             # Optional, default: empty map
#        my_label_key: my_label_value
#cert:
#  - name: my-cert                                         # Required
#    description: "Description of entry"                   # Optional, default: ""
#    domain: "*"                                           # Optional, default: "*"
#    caPath: "certs/ca.pem"                                # Optional, default: ""
#    certPemPath: "certs/server-cert.pem"                  # Optional, default: ""
#    keyPemPath: "certs/server-key.pem"                    # Optional, default: ""
#config:
#  - name: my-config                                       # Required
#    description: "Description of entry"                   # Optional, default: ""
#    domain: "*"                                           # Optional, default: "*"
#    path: "config/config.yaml"                            # Optional
#    envPrefix: ""                                         # Optional, default: ""
#    content:                                              # Optional, defualt: empty map
#      key: value
mux:
  - name: greeter                                          # Required
    port: 8080                                             # Required
    enabled: true                                          # Required
#    description: "greeter server"                         # Optional, default: ""
#    certEntry: my-cert                                    # Optional, default: "", reference of cert entry declared above
#    loggerEntry: my-logger                                # Optional, default: "", reference of cert entry declared above, STDOUT will be used if missing
#    eventEntry: my-event                                  # Optional, default: "", reference of cert entry declared above, STDOUT will be used if missing
#    sw:
#      enabled: true                                       # Optional, default: false
#      path: "sw"                                          # Optional, default: "sw"
#      jsonPath: [""]                                      # Optional
#      headers: ["sw:rk"]                                  # Optional, default: []
#    docs:
#      enabled: true                                       # Optional, default: false
#      path: "docs"                                        # Optional, default: "docs"
#      specPath: ""                                        # Optional
#      headers: ["sw:rk"]                                  # Optional, default: []
#      style:                                              # Optional
#        theme: "light"                                    # Optional, default: "light"
#      debug: false                                        # Optional, default: false
#    commonService:
#      enabled: true                                       # Optional, default: false
#      pathPrefix: ""                                      # Optional, default: "/rk/v1/"
#    static:
#      enabled: true                                       # Optional, default: false
#      path: "/static"                                     # Optional, default: /static
#      sourceType: local                                   # Optional, options: local, embed.FS can be used either, need to specify in code
#      sourcePath: "."                                     # Optional, full path of source directory
#    pprof:
#      enabled: true                                       # Optional, default: false
#      path: "/pprof"                                      # Optional, default: /pprof
#    prom:
#      enabled: true                                       # Optional, default: false
#      path: ""                                            # Optional, default: "/metrics"
#      pusher:
#        enabled: false                                    # Optional, default: false
#        jobName: "greeter-pusher"                         # Required
#        remoteAddress: "localhost:9091"                   # Required
#        basicAuth: "user:pass"                            # Optional, default: ""
#        intervalMs: 10000                                 # Optional, default: 1000
#        certEntry: my-cert                                # Optional, default: "", reference of cert entry declared above
#    middleware:
#      ignore: [""]                                        # Optional, default: []
#      errorModel: google                                  # Optional, default: google, [amazon, google] are supported options
#      logging:
#        enabled: true                                     # Optional, default: false
#        ignore: [""]                                      # Optional, default: []
#        loggerEncoding: "console"                         # Optional, default: "console"
#        loggerOutputPaths: ["logs/app.log"]               # Optional, default: ["stdout"]
#        eventEncoding: "console"                          # Optional, default: "console"
#        eventOutputPaths: ["logs/event.log"]              # Optional, default: ["stdout"]
#      prom:
#        enabled: true                                     # Optional, default: false
#        ignore: [""]                                      # Optional, default: []
#      auth:
#        enabled: true                                     # Optional, default: false
#        ignore: [""]                                      # Optional, default: []
#        basic:
#          - "user:pass"                                   # Optional, default: []
#        apiKey:
#          - "keys"                                        # Optional, default: []
#      meta:
#        enabled: true                                     # Optional, default: false
#        ignore: [""]                                      # Optional, default: []
#        prefix: "rk"                                      # Optional, default: "rk"
#      trace:
#        enabled: true                                     # Optional, default: false
#        ignore: [""]                                      # Optional, default: []
#        exporter:                                         # Optional, default will create a stdout exporter
#          file:
#            enabled: true                                 # Optional, default: false
#            outputPath: "logs/trace.log"                  # Optional, default: stdout
#          jaeger:
#            agent:
#              enabled: false                              # Optional, default: false
#              host: ""                                    # Optional, default: localhost
#              port: 0                                     # Optional, default: 6831
#            collector:
#              enabled: true                               # Optional, default: false
#              endpoint: ""                                # Optional, default: http://localhost:14268/api/traces
#              username: ""                                # Optional, default: ""
#              password: ""                                # Optional, default: ""
#      rateLimit:
#        enabled: false                                    # Optional, default: false
#        ignore: [""]                                      # Optional, default: []
#        algorithm: "leakyBucket"                          # Optional, default: "tokenBucket"
#        reqPerSec: 100                                    # Optional, default: 1000000
#        paths:
#          - path: "/rk/v1/healthy"                        # Optional, default: ""
#            reqPerSec: 0                                  # Optional, default: 1000000
#      jwt:
#        enabled: true                                     # Optional, default: false
#        ignore: [ "" ]                                    # Optional, default: []
#        skipVerify: false                                 # Optional, default: false
#        signerEntry: ""                                   # Optional, default: ""
#        symmetric:                                        # Optional
#          algorithm: ""                                   # Required, default: ""
#          token: ""                                       # Optional, default: ""
#          tokenPath: ""                                   # Optional, default: ""
#        asymmetric:                                       # Optional
#          algorithm: ""                                   # Required, default: ""
#          privateKey: ""                                  # Optional, default: ""
#          privateKeyPath: ""                              # Optional, default: ""
#          publicKey: ""                                   # Optional, default: ""
#          publicKeyPath: ""                               # Optional, default: ""
#        tokenLookup: "header:<name>"                      # Optional, default: "header:Authorization"
#        authScheme: "Bearer"                              # Optional, default: "Bearer"
#      secure:
#        enabled: true                                     # Optional, default: false
#        ignore: [""]                                      # Optional, default: []
#        xssProtection: ""                                 # Optional, default: "1; mode=block"
#        contentTypeNosniff: ""                            # Optional, default: nosniff
#        xFrameOptions: ""                                 # Optional, default: SAMEORIGIN
#        hstsMaxAge: 0                                     # Optional, default: 0
#        hstsExcludeSubdomains: false                      # Optional, default: false
#        hstsPreloadEnabled: false                         # Optional, default: false
#        contentSecurityPolicy: ""                         # Optional, default: ""
#        cspReportOnly: false                              # Optional, default: false
#        referrerPolicy: ""                                # Optional, default: ""
#      csrf:
#        enabled: true                                     # Optional, default: false
#        ignore: [""]                                      # Optional, default: []
#        tokenLength: 32                                   # Optional, default: 32
#        tokenLookup: "header:X-CSRF-Token"                # Optional, default: "header:X-CSRF-Token"
#        cookieName: "_csrf"                               # Optional, default: _csrf
#        cookieDomain: ""                                  # Optional, default: ""
#        cookiePath: ""                                    # Optional, default: ""
#        cookieMaxAge: 86400                               # Optional, default: 86400
#        cookieHttpOnly: false                             # Optional, default: false
#        cookieSameSite: "default"                         # Optional, default: "default", options: lax, strict, none, default
#      cors:
#        enabled: true                                     # Optional, default: false
#        ignore: [""]                                      # Optional, default: []
#        allowOrigins:                                     # Optional, default: []
#          - "http://localhost:*"                          # Optional, default: *
#        allowCredentials: false                           # Optional, default: false
#        allowHeaders: []                                  # Optional, default: []
#        allowMethods: []                                  # Optional, default: []
#        exposeHeaders: []                                 # Optional, default: []
#        maxAge: 0                                         # Optional, default: 0

Development Status: Testing

Build instruction

Simply run make all to validate your changes. Or run codes in example/ folder.

  • make all

Run unit-test, golangci-lint, doctoc and gofmt.

Test instruction

Run unit test with make test command.

github workflow will automatically run unit test and golangci-lint for testing and lint validation.

Contributing

We encourage and support an active, healthy community of contributors — including you! Details are in the contribution guide and the code of conduct. The rk maintainers keep an eye on issues and pull requests, but you can also report any negative conduct to [email protected].

Released under the Apache 2.0 License.