{"id":19484067,"url":"https://github.com/rookie-ninja/rk-echo","last_synced_at":"2025-04-25T16:33:18.791Z","repository":{"id":38403367,"uuid":"422908540","full_name":"rookie-ninja/rk-echo","owner":"rookie-ninja","description":"Start echo microservice from YAML, plugin of rk-boot","archived":false,"fork":false,"pushed_at":"2023-10-31T12:38:45.000Z","size":17515,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-10-31T13:35:16.604Z","etag":null,"topics":["bootstrapper","echo","echo-framework","golang","middlewares"],"latest_commit_sha":null,"homepage":"https://rkdev.info","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rookie-ninja.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-10-30T14:46:45.000Z","updated_at":"2023-09-18T14:48:02.000Z","dependencies_parsed_at":"2023-01-31T03:15:58.355Z","dependency_job_id":"4696f66e-82ee-42a7-aebc-3b1f00ba91f8","html_url":"https://github.com/rookie-ninja/rk-echo","commit_stats":null,"previous_names":[],"tags_count":40,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rookie-ninja%2Frk-echo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rookie-ninja%2Frk-echo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rookie-ninja%2Frk-echo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rookie-ninja%2Frk-echo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rookie-ninja","download_url":"https://codeload.github.com/rookie-ninja/rk-echo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224008616,"owners_count":17240417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bootstrapper","echo","echo-framework","golang","middlewares"],"created_at":"2024-11-10T20:19:06.474Z","updated_at":"2024-11-10T20:19:08.050Z","avatar_url":"https://github.com/rookie-ninja.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch2 align=\"center\"\u003e\n  rk-echo\n\u003c/h2\u003e\n\u003cp align=\"center\"\u003e\n  Inject middlewares \u0026 server configuration of \u003ca href=\"https://github.com/labstack/echo\"\u003elabstack/echo\u003c/a\u003e from YAML file.\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  This belongs to \u003ca href=\"https://github.com/rookie-ninja/rk-boot\"\u003erk-boot\u003c/a\u003e family. We suggest use this lib with \u003ca href=\"https://github.com/rookie-ninja/rk-boot\"\u003erk-boot\u003c/a\u003e.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n \u003ca href=\"https://github.com/rookie-ninja/rk-echo/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/rookie-ninja/rk-echo/actions/workflows/ci.yml/badge.svg\"\u003e\u003c/a\u003e\n \u003ca href=\"https://codecov.io/gh/rookie-ninja/rk-echo\"\u003e\u003cimg src=\"https://codecov.io/gh/rookie-ninja/rk-echo/branch/master/graph/badge.svg?token=08TCFIIVS0\"\u003e\u003c/a\u003e\n \u003ca href=\"https://goreportcard.com/badge/github.com/rookie-ninja/rk-echo\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/rookie-ninja/rk-echo\"\u003e\u003c/a\u003e\n \u003ca href=\"https://sourcegraph.com/github.com/rookie-ninja/rk-echo?badge\"\u003e\u003cimg src=\"https://sourcegraph.com/github.com/rookie-ninja/rk-echo/-/badge.svg\"\u003e\u003c/a\u003e\n \u003ca href=\"https://godoc.org/github.com/rookie-ninja/rk-echo\"\u003e\u003cimg src=\"https://godoc.org/github.com/rookie-ninja/rk-echo?status.svg\"\u003e\u003c/a\u003e\n \u003ca href=\"https://github.com/rookie-ninja/rk-echo/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/release/rookie-ninja/rk-echo.svg?style=flat-square\"\u003e\u003c/a\u003e\n \u003ca href=\"https://opensource.org/licenses/Apache-2.0\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-Apache%202.0-blue.svg\"\u003e\u003c/a\u003e\n\u003cp\u003e\n\n\u003cdiv id=\"badges\" align=\"center\"\u003e\n  \u003ca href=\"https://rkdev.info\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Official Site-blue?logo=mdbook\u0026logoColor=white\u0026style=for-the-badge\" alt=\"Docs Badge\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://rk-syz1767.slack.com/rk-boot\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Slack-4A154B?style=for-the-badge\u0026logo=slack\u0026logoColor=white\" alt=\"Docs Badge\"/\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n## Architecture\n![image](docs/img/echo-arch.png)\n\n## Quick Start\nIn the bellow example, we will start microservice with bellow functionality and middlewares enabled via YAML.\n\n- [labstack/echo](https://github.com/labstack/echo) server\n- Swagger UI\n- Docs\n- CommonService\n- Prometheus Metrics (middleware)\n- Logging (middleware)\n- Meta (middleware)\n\nPlease refer example at [example/boot/simple](example/boot/simple).\n\n### Installation\n```shell\ngo get github.com/rookie-ninja/rk-echo\n```\n\n### 1.Create boot.yaml\n- [boot.yaml](example/boot/simple/boot.yaml)\n\n\u003cdetails\u003e\n\u003csummary\u003eshow\u003c/summary\u003e\n\n```yaml\n---\necho:\n  - name: greeter                     # Required\n    port: 8080                        # Required\n    enabled: true                     # Required\n    commonService:                    # Optional\n      enabled: true                   # Optional, default: false\n    sw:                               # Optional\n      enabled: true                   # Optional, default: false\n    docs:                             # Optional\n      enabled: true                   # Optional, default: false\n    prom:\n      enabled: true                   # Optional, default: false\n    middleware:\n      logging:\n        enabled: true\n      prom:\n        enabled: true\n      meta:\n        enabled: true\n```\n\n\u003c/details\u003e\n\n### 2.Create main.go\n- [main.go](example/boot/simple/main.go)\n\n\u003cdetails\u003e\n\u003csummary\u003eshow\u003c/summary\u003e\n\n```go\n// Copyright (c) 2021 rookie-ninja\n//\n// Use of this source code is governed by an Apache-style\n// license that can be found in the LICENSE file.\npackage main\n\nimport (\n\t\"context\"\n\t\"embed\"\n\t_ \"embed\"\n\t\"fmt\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/rookie-ninja/rk-echo/boot\"\n\t\"github.com/rookie-ninja/rk-entry/v2/entry\"\n\t\"net/http\"\n)\n\n// How to use embed.FS for:\n//\n// - boot.yaml\n// - rkentry.DocsEntryType\n// - rkentry.SWEntryType\n// - rkentry.StaticFileHandlerEntryType\n// - rkentry.CertEntry\n//\n// If we use embed.FS, then we only need one single binary file while packing.\n// We suggest use embed.FS to pack swagger local file since rk-entry would use os.Getwd() to look for files\n// if relative path was provided.\n//\n//go:embed docs\nvar docsFS embed.FS\n\nfunc init() {\n\trkentry.GlobalAppCtx.AddEmbedFS(rkentry.SWEntryType, \"greeter\", \u0026docsFS)\n}\n\n//go:embed boot.yaml\nvar boot []byte\n\n// @title RK Swagger for Echo\n// @version 1.0\n// @description This is a greeter service with rk-boot.\nfunc main() {\n\t// Bootstrap preload entries\n\trkentry.BootstrapPreloadEntryYAML(boot)\n\n\t// Bootstrap echo entry from boot config\n\tres := rkecho.RegisterEchoEntryYAML(boot)\n\n\t// Get EchoEntry\n\techoEntry := res[\"greeter\"].(*rkecho.EchoEntry)\n\t// Use *echo.Echo adding handler.\n\techoEntry.Echo.GET(\"/v1/greeter\", Greeter)\n\n\t// Bootstrap echo entry\n\techoEntry.Bootstrap(context.Background())\n\n\t// Wait for shutdown signal\n\trkentry.GlobalAppCtx.WaitForShutdownSig()\n\n\t// Interrupt echo entry\n\techoEntry.Interrupt(context.Background())\n}\n\n// Greeter handler\n// @Summary Greeter service\n// @Id 1\n// @version 1.0\n// @produce application/json\n// @Param name query string true \"Input name\"\n// @Success 200 {object} GreeterResponse\n// @Router /v1/greeter [get]\nfunc Greeter(ctx echo.Context) error {\n\treturn ctx.JSON(http.StatusOK, \u0026GreeterResponse{\n\t\tMessage: fmt.Sprintf(\"Hello %s!\", ctx.QueryParam(\"name\")),\n\t})\n}\n\ntype GreeterResponse struct {\n\tMessage string\n}\n```\n\n\u003c/details\u003e\n\n### 3.Start server\n\n```go\n$ go run main.go\n```\n\n### 4.Validation\n\n\u003cdetails\u003e\n\u003csummary\u003eshow\u003c/summary\u003e\n\n#### 4.1 Echo server\nTry to test Echo Service with [curl](https://curl.se/)\n\n```shell script\n# Curl to common service\n$ curl localhost:8080/rk/v1/ready\n{\n  \"ready\": true\n}\n\n$ curl localhost:8080/rk/v1/alive\n{\n  \"alive\": true\n}\n```\n\n#### 4.2 Swagger UI\nPlease refer **sw** section at [Full YAML](#full-yaml).\n\nBy default, we could access swagger UI at [http://localhost:8080/sw](http://localhost:8080/sw)\n\n![sw](docs/img/simple-sw.png)\n\n#### 4.3 Docs UI\nPlease refer **docs** section at [Full YAML](#full-yaml).\n\nBy default, we could access docs UI at [http://localhost:8080/docs](http://localhost:8080/docs)\n\n![docs](docs/img/simple-docs.png)\n\n#### 4.4 Prometheus Metrics\nPlease refer **middleware.prom** section at [Full YAML](#full-yaml).\n\nBy default, we could access prometheus client at [http://localhost:8080/metrics](http://localhost:8080/metrics)\n- http://localhost:8080/metrics\n\n![prom](docs/img/simple-prom.png)\n\n#### 4.5 Logging\nPlease refer **middleware.logging** section at [Full YAML](#full-yaml).\n\nBy default, we enable zap logger and event logger with encoding type of [console]. Encoding type of [json] is also supported.\n\n```shell script\n2021-12-27T22:18:31.466+0800    INFO    boot/echo_entry.go:1106 Bootstrap echoEntry     {\"eventId\": \"f01c3418-d48f-432f-9391-ad6a7567d0f8\", \"entryName\": \"greeter\"}\n------------------------------------------------------------------------\nendTime=2021-12-27T22:18:31.468366+08:00\nstartTime=2021-12-27T22:18:31.466905+08:00\nelapsedNano=1460123\ntimezone=CST\nids={\"eventId\":\"f01c3418-d48f-432f-9391-ad6a7567d0f8\"}\napp={\"appName\":\"rk\",\"appVersion\":\"\",\"entryName\":\"greeter\",\"entryType\":\"EchoEntry\"}\nenv={\"arch\":\"amd64\",\"az\":\"*\",\"domain\":\"*\",\"hostname\":\"lark.local\",\"localIP\":\"10.8.0.2\",\"os\":\"darwin\",\"realm\":\"*\",\"region\":\"*\"}\npayloads={\"commonServiceEnabled\":true,\"commonServicePathPrefix\":\"/rk/v1/\",\"promEnabled\":true,\"promPath\":\"/metrics\",\"promPort\":8080,\"swEnabled\":true,\"swPath\":\"/sw/\",\"tvEnabled\":true,\"tvPath\":\"/rk/v1/tv/\"}\nerror={}\ncounters={}\npairs={}\ntiming={}\nremoteAddr=localhost\noperation=Bootstrap\nresCode=OK\neventStatus=Ended\nEOE\n```\n\n#### 4.6 Meta\nPlease refer **meta** section at [Full YAML](#full-yaml).\n\nBy default, we will send back some metadata to client including gateway with headers.\n\n```shell script\n$ curl -vs localhost:8080/rk/v1/ready\n...\n\u003c HTTP/1.1 200 OK\n\u003c Content-Type: application/json; charset=utf-8\n\u003c X-Request-Id: 3332e575-43d8-4bfe-84dd-45b5fc5fb104\n\u003c X-Rk-App-Name: rk-echo\n\u003c X-Rk-App-Unix-Time: 2021-06-25T01:30:45.143869+08:00\n\u003c X-Rk-App-Version: master-xxx\n\u003c X-Rk-Received-Time: 2021-06-25T01:30:45.143869+08:00\n\u003c X-Trace-Id: 65b9aa7a9705268bba492fdf4a0e5652\n\u003c Date: Thu, 24 Jun 2021 17:30:45 GMT\n...\n```\n\n#### 4.7 Send request\nWe registered /v1/greeter API in [labstack/echo](https://github.com/labstack/echo) server and let's validate it!\n\n```shell script\n$ curl -vs \"localhost:8080/v1/greeter?name=rk-dev\"\n*   Trying ::1...\n* TCP_NODELAY set\n* Connected to localhost (::1) port 8080 (#0)\n\u003e GET /v1/greeter?name=rk-dev HTTP/1.1\n\u003e Host: localhost:8080\n\u003e User-Agent: curl/7.64.1\n\u003e Accept: */*\n\u003e\n\u003c HTTP/1.1 200 OK\n\u003c Content-Type: application/json; charset=UTF-8\n\u003c X-Request-Id: 958a345d-8ded-4cc3-a762-35de01fd80c3\n\u003c X-Rk-App-Name: rk\n\u003c X-Rk-App-Unix-Time: 2021-12-28T01:42:01.429863+08:00\n\u003c X-Rk-App-Version:\n\u003c X-Rk-Received-Time: 2021-12-28T01:42:01.429863+08:00\n\u003c Date: Mon, 27 Dec 2021 17:42:01 GMT\n\u003c Content-Length: 28\n\u003c\n{\"Message\":\"Hello rk-dev!\"}\n```\n\n#### 4.8 RPC logs\nBellow logs would be printed in stdout.\n\n```\n------------------------------------------------------------------------\nendTime=2021-12-28T01:42:01.430018+08:00\nstartTime=2021-12-28T01:42:01.429847+08:00\nelapsedNano=170643\ntimezone=CST\nids={\"eventId\":\"958a345d-8ded-4cc3-a762-35de01fd80c3\",\"requestId\":\"958a345d-8ded-4cc3-a762-35de01fd80c3\"}\napp={\"appName\":\"rk\",\"appVersion\":\"\",\"entryName\":\"greeter\",\"entryType\":\"EchoEntry\"}\nenv={\"arch\":\"amd64\",\"az\":\"*\",\"domain\":\"*\",\"hostname\":\"lark.local\",\"localIP\":\"192.168.101.5\",\"os\":\"darwin\",\"realm\":\"*\",\"region\":\"*\"}\npayloads={\"apiMethod\":\"GET\",\"apiPath\":\"/v1/greeter\",\"apiProtocol\":\"HTTP/1.1\",\"apiQuery\":\"name=rk-dev\",\"userAgent\":\"curl/7.64.1\"}\nerror={}\ncounters={}\npairs={}\ntiming={}\nremoteAddr=localhost:59114\noperation=/v1/greeter\nresCode=200\neventStatus=Ended\nEOE\n```\n\n#### 4.9 RPC prometheus metrics\nPrometheus client will automatically register into [labstack/echo](https://github.com/labstack/echo) instance at /metrics.\n\nAccess [http://localhost:8080/metrics](http://localhost:8080/metrics)\n\n![image](docs/img/prom-inter.png)\n\n\u003c/details\u003e\n\n## Supported features\n**User can enable anyone of those as needed! No mandatory binding!**\n\n| Instance          | Description                                                                                                   |\n|-------------------|---------------------------------------------------------------------------------------------------------------|\n| Echo              | Compatible with original [labstack/echo](https://github.com/labstack/echo) service functionalities            |\n| Config            | Configure [spf13/viper](https://github.com/spf13/viper) as config instance and reference it from YAML         |\n| Logger            | Configure [uber-go/zap](https://github.com/uber-go/zap) logger configuration and reference it from YAML       |\n| Event             | Configure logging of RPC with [rk-query](https://github.com/rookie-ninja/rk-query) and reference it from YAML |\n| Cert              | Fetch TLS/SSL certificates start microservice.                                                                |\n| Prometheus        | Start prometheus client at client side and push metrics to pushgateway as needed.                             |\n| Swagger           | Builtin swagger UI handler.                                                                                   |\n| Docs              | Builtin [RapiDoc](https://github.com/mrin9/RapiDoc) instance which can be used to replace swagger and RK TV.  |\n| CommonService     | List of common APIs.                                                                                          |\n| StaticFileHandler | A Web UI shows files could be downloaded from server, currently support source of local and embed.FS.         |\n| PProf             | PProf web UI.                                                                                                 |\n\n## Supported middlewares\nAll middlewares could be configured via YAML or Code.\n\n**User can enable anyone of those as needed! No mandatory binding!**\n\n| Middleware | Description                                                                                                                                           |\n|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Prom       | Collect RPC metrics and export to [prometheus](https://github.com/prometheus/client_golang) client.                                                   |\n| Logging    | Log every RPC requests as event with [rk-query](https://github.com/rookie-ninja/rk-query).                                                            |\n| Trace      | Collect RPC trace and export it to stdout, file or jaeger with [open-telemetry/opentelemetry-go](https://github.com/open-telemetry/opentelemetry-go). |\n| Panic      | Recover from panic for RPC requests and log it.                                                                                                       |\n| Meta       | Send micsro service metadata as header to client.                                                                                                     |\n| Auth       | Support [Basic Auth] and [API Key] authorization types.                                                                                               |\n| RateLimit  | Limiting RPC rate globally or per path.                                                                                                               |\n| Timeout    | Timing out request by configuration.                                                                                                                  |\n| Gzip       | Compress and Decompress message body based on request header with gzip format .                                                                       |\n| CORS       | Server side CORS validation.                                                                                                                          |\n| JWT        | Server side JWT validation.                                                                                                                           |\n| Secure     | Server side secure validation.                                                                                                                        |\n| CSRF       | Server side csrf validation.                                                                                                                          |\n\n\n## YAML Options\nUser can start multiple [labstack/echo](https://github.com/labstack/echo) instances at the same time. Please make sure use different port and name.\n\n\u003cdetails\u003e\n\u003csummary\u003eshow\u003c/summary\u003e\n\n```yaml\n---\n#app:\n#  name: my-app                                            # Optional, default: \"rk-app\"\n#  version: \"v1.0.0\"                                       # Optional, default: \"v0.0.0\"\n#  description: \"this is description\"                      # Optional, default: \"\"\n#  keywords: [\"rk\", \"golang\"]                              # Optional, default: []\n#  homeUrl: \"http://example.com\"                           # Optional, default: \"\"\n#  docsUrl: [\"http://example.com\"]                         # Optional, default: []\n#  maintainers: [\"rk-dev\"]                                 # Optional, default: []\n#logger:\n#  - name: my-logger                                       # Required\n#    description: \"Description of entry\"                   # Optional\n#    domain: \"*\"                                           # Optional, default: \"*\"\n#    default: false                                        # Optional, default: false, use as default logger entry\n#    zap:                                                  # Optional\n#      level: info                                         # Optional, default: info\n#      development: true                                   # Optional, default: true\n#      disableCaller: false                                # Optional, default: false\n#      disableStacktrace: true                             # Optional, default: true\n#      encoding: console                                   # Optional, default: console\n#      outputPaths: [\"stdout\"]                             # Optional, default: [stdout]\n#      errorOutputPaths: [\"stderr\"]                        # Optional, default: [stderr]\n#      encoderConfig:                                      # Optional\n#        timeKey: \"ts\"                                     # Optional, default: ts\n#        levelKey: \"level\"                                 # Optional, default: level\n#        nameKey: \"logger\"                                 # Optional, default: logger\n#        callerKey: \"caller\"                               # Optional, default: caller\n#        messageKey: \"msg\"                                 # Optional, default: msg\n#        stacktraceKey: \"stacktrace\"                       # Optional, default: stacktrace\n#        skipLineEnding: false                             # Optional, default: false\n#        lineEnding: \"\\n\"                                  # Optional, default: \\n\n#        consoleSeparator: \"\\t\"                            # Optional, default: \\t\n#      sampling:                                           # Optional, default: nil\n#        initial: 0                                        # Optional, default: 0\n#        thereafter: 0                                     # Optional, default: 0\n#      initialFields:                                      # Optional, default: empty map\n#        key: value\n#    lumberjack:                                           # Optional, default: nil\n#      filename:\n#      maxsize: 1024                                       # Optional, suggested: 1024 (MB)\n#      maxage: 7                                           # Optional, suggested: 7 (day)\n#      maxbackups: 3                                       # Optional, suggested: 3 (day)\n#      localtime: true                                     # Optional, suggested: true\n#      compress: true                                      # Optional, suggested: true\n#    loki:\n#      enabled: true                                       # Optional, default: false\n#      addr: localhost:3100                                # Optional, default: localhost:3100\n#      path: /loki/api/v1/push                             # Optional, default: /loki/api/v1/push\n#      username: \"\"                                        # Optional, default: \"\"\n#      password: \"\"                                        # Optional, default: \"\"\n#      maxBatchWaitMs: 3000                                # Optional, default: 3000\n#      maxBatchSize: 1000                                  # Optional, default: 1000\n#      insecureSkipVerify: false                           # Optional, default: false\n#      labels:                                             # Optional, default: empty map\n#        my_label_key: my_label_value\n#event:\n#  - name: my-event                                        # Required\n#    description: \"Description of entry\"                   # Optional\n#    domain: \"*\"                                           # Optional, default: \"*\"\n#    default: false                                        # Optional, default: false, use as default event entry\n#    encoding: console                                     # Optional, default: console\n#    outputPaths: [\"stdout\"]                               # Optional, default: [stdout]\n#    lumberjack:                                           # Optional, default: nil\n#      filename:\n#      maxsize: 1024                                       # Optional, suggested: 1024 (MB)\n#      maxage: 7                                           # Optional, suggested: 7 (day)\n#      maxbackups: 3                                       # Optional, suggested: 3 (day)\n#      localtime: true                                     # Optional, suggested: true\n#      compress: true                                      # Optional, suggested: true\n#    loki:\n#      enabled: true                                       # Optional, default: false\n#      addr: localhost:3100                                # Optional, default: localhost:3100\n#      path: /loki/api/v1/push                             # Optional, default: /loki/api/v1/push\n#      username: \"\"                                        # Optional, default: \"\"\n#      password: \"\"                                        # Optional, default: \"\"\n#      maxBatchWaitMs: 3000                                # Optional, default: 3000\n#      maxBatchSize: 1000                                  # Optional, default: 1000\n#      insecureSkipVerify: false                           # Optional, default: false\n#      labels:                                             # Optional, default: empty map\n#        my_label_key: my_label_value\n#cert:\n#  - name: my-cert                                         # Required\n#    description: \"Description of entry\"                   # Optional, default: \"\"\n#    domain: \"*\"                                           # Optional, default: \"*\"\n#    caPath: \"certs/ca.pem\"                                # Optional, default: \"\"\n#    certPemPath: \"certs/server-cert.pem\"                  # Optional, default: \"\"\n#    keyPemPath: \"certs/server-key.pem\"                    # Optional, default: \"\"\n#config:\n#  - name: my-config                                       # Required\n#    description: \"Description of entry\"                   # Optional, default: \"\"\n#    domain: \"*\"                                           # Optional, default: \"*\"\n#    path: \"config/config.yaml\"                            # Optional\n#    envPrefix: \"\"                                         # Optional, default: \"\"\n#    content:                                              # Optional, defualt: empty map\n#      key: value\necho:\n  - name: greeter                                          # Required\n    port: 8080                                             # Required\n    enabled: true                                          # Required\n#    description: \"greeter server\"                         # Optional, default: \"\"\n#    certEntry: my-cert                                    # Optional, default: \"\", reference of cert entry declared above\n#    loggerEntry: my-logger                                # Optional, default: \"\", reference of cert entry declared above, STDOUT will be used if missing\n#    eventEntry: my-event                                  # Optional, default: \"\", reference of cert entry declared above, STDOUT will be used if missing\n#    sw:\n#      enabled: true                                       # Optional, default: false\n#      path: \"sw\"                                          # Optional, default: \"sw\"\n#      jsonPath: [\"\"]                                      # Optional\n#      headers: [\"sw:rk\"]                                  # Optional, default: []\n#    docs:\n#      enabled: true                                       # Optional, default: false\n#      path: \"docs\"                                        # Optional, default: \"docs\"\n#      specPath: \"\"                                        # Optional\n#      headers: [\"sw:rk\"]                                  # Optional, default: []\n#      style:                                              # Optional\n#        theme: \"light\"                                    # Optional, default: \"light\"\n#      debug: false                                        # Optional, default: false\n#    commonService:\n#      enabled: true                                       # Optional, default: false\n#      pathPrefix: \"\"                                      # Optional, default: \"/rk/v1/\"\n#    static:\n#      enabled: true                                       # Optional, default: false\n#      path: \"/static\"                                     # Optional, default: /static\n#      sourceType: local                                   # Optional, options: local, embed.FS can be used either, need to specify in code\n#      sourcePath: \".\"                                     # Optional, full path of source directory\n#    pprof:\n#      enabled: true                                       # Optional, default: false\n#      path: \"/pprof\"                                      # Optional, default: /pprof\n#    prom:\n#      enabled: true                                       # Optional, default: false\n#      path: \"\"                                            # Optional, default: \"/metrics\"\n#      pusher:\n#        enabled: false                                    # Optional, default: false\n#        jobName: \"greeter-pusher\"                         # Required\n#        remoteAddress: \"localhost:9091\"                   # Required\n#        basicAuth: \"user:pass\"                            # Optional, default: \"\"\n#        intervalMs: 10000                                 # Optional, default: 1000\n#        certEntry: my-cert                                # Optional, default: \"\", reference of cert entry declared above\n#    middleware:\n#      ignore: [\"\"]                                        # Optional, default: []\n#      errorModel: google                                  # Optional, default: google, [amazon, google] are supported options\n#      logging:\n#        enabled: true                                     # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#        loggerEncoding: \"console\"                         # Optional, default: \"console\"\n#        loggerOutputPaths: [\"logs/app.log\"]               # Optional, default: [\"stdout\"]\n#        eventEncoding: \"console\"                          # Optional, default: \"console\"\n#        eventOutputPaths: [\"logs/event.log\"]              # Optional, default: [\"stdout\"]\n#      prom:\n#        enabled: true                                     # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#      auth:\n#        enabled: true                                     # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#        basic:\n#          - \"user:pass\"                                   # Optional, default: []\n#        apiKey:\n#          - \"keys\"                                        # Optional, default: []\n#      meta:\n#        enabled: true                                     # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#        prefix: \"rk\"                                      # Optional, default: \"rk\"\n#      trace:\n#        enabled: true                                     # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#        exporter:                                         # Optional, default will create a stdout exporter\n#          file:\n#            enabled: true                                 # Optional, default: false\n#            outputPath: \"logs/trace.log\"                  # Optional, default: stdout\n#          jaeger:\n#            agent:\n#              enabled: false                              # Optional, default: false\n#              host: \"\"                                    # Optional, default: localhost\n#              port: 0                                     # Optional, default: 6831\n#            collector:\n#              enabled: true                               # Optional, default: false\n#              endpoint: \"\"                                # Optional, default: http://localhost:14268/api/traces\n#              username: \"\"                                # Optional, default: \"\"\n#              password: \"\"                                # Optional, default: \"\"\n#      rateLimit:\n#        enabled: false                                    # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#        algorithm: \"leakyBucket\"                          # Optional, default: \"tokenBucket\"\n#        reqPerSec: 100                                    # Optional, default: 1000000\n#        paths:\n#          - path: \"/rk/v1/healthy\"                        # Optional, default: \"\"\n#            reqPerSec: 0                                  # Optional, default: 1000000\n#      timeout:\n#        enabled: false                                    # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#        timeoutMs: 5000                                   # Optional, default: 5000\n#        paths:\n#          - path: \"/rk/v1/healthy\"                        # Optional, default: \"\"\n#            timeoutMs: 1000                               # Optional, default: 5000\n#      jwt:\n#        enabled: true                                     # Optional, default: false\n#        ignore: [ \"\" ]                                    # Optional, default: []\n#        skipVerify: false                                 # Optional, default: false\n#        signerEntry: \"\"                                   # Optional, default: \"\"\n#        symmetric:                                        # Optional\n#          algorithm: \"\"                                   # Required, default: \"\"\n#          token: \"\"                                       # Optional, default: \"\"\n#          tokenPath: \"\"                                   # Optional, default: \"\"\n#        asymmetric:                                       # Optional\n#          algorithm: \"\"                                   # Required, default: \"\"\n#          privateKey: \"\"                                  # Optional, default: \"\"\n#          privateKeyPath: \"\"                              # Optional, default: \"\"\n#          publicKey: \"\"                                   # Optional, default: \"\"\n#          publicKeyPath: \"\"                               # Optional, default: \"\"\n#        tokenLookup: \"header:\u003cname\u003e\"                      # Optional, default: \"header:Authorization\"\n#        authScheme: \"Bearer\"                              # Optional, default: \"Bearer\"\n#      secure:\n#        enabled: true                                     # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#        xssProtection: \"\"                                 # Optional, default: \"1; mode=block\"\n#        contentTypeNosniff: \"\"                            # Optional, default: nosniff\n#        xFrameOptions: \"\"                                 # Optional, default: SAMEORIGIN\n#        hstsMaxAge: 0                                     # Optional, default: 0\n#        hstsExcludeSubdomains: false                      # Optional, default: false\n#        hstsPreloadEnabled: false                         # Optional, default: false\n#        contentSecurityPolicy: \"\"                         # Optional, default: \"\"\n#        cspReportOnly: false                              # Optional, default: false\n#        referrerPolicy: \"\"                                # Optional, default: \"\"\n#      csrf:\n#        enabled: true                                     # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#        tokenLength: 32                                   # Optional, default: 32\n#        tokenLookup: \"header:X-CSRF-Token\"                # Optional, default: \"header:X-CSRF-Token\"\n#        cookieName: \"_csrf\"                               # Optional, default: _csrf\n#        cookieDomain: \"\"                                  # Optional, default: \"\"\n#        cookiePath: \"\"                                    # Optional, default: \"\"\n#        cookieMaxAge: 86400                               # Optional, default: 86400\n#        cookieHttpOnly: false                             # Optional, default: false\n#        cookieSameSite: \"default\"                         # Optional, default: \"default\", options: lax, strict, none, default\n#      gzip:\n#        enabled: true                                     # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#        level: bestSpeed                                  # Optional, options: [noCompression, bestSpeed， bestCompression, defaultCompression, huffmanOnly]\n#      cors:\n#        enabled: true                                     # Optional, default: false\n#        ignore: [\"\"]                                      # Optional, default: []\n#        allowOrigins:                                     # Optional, default: []\n#          - \"http://localhost:*\"                          # Optional, default: *\n#        allowCredentials: false                           # Optional, default: false\n#        allowHeaders: []                                  # Optional, default: []\n#        allowMethods: []                                  # Optional, default: []\n#        exposeHeaders: []                                 # Optional, default: []\n#        maxAge: 0                                         # Optional, default: 0\n```\n\n\u003c/details\u003e\n\n## Development Status: Stable\n\n## Build instruction\nSimply run make all to validate your changes. Or run codes in example/ folder.\n\n- make all\n\nRun unit-test, golangci-lint, doctoc and gofmt.\n\n## Test instruction\nRun unit test with **make test** command.\n\ngithub workflow will automatically run unit test and golangci-lint for testing and lint validation.\n\n## Contributing\nWe encourage and support an active, healthy community of contributors \u0026mdash;\nincluding you! Details are in the [contribution guide](CONTRIBUTING.md) and\nthe [code of conduct](CODE_OF_CONDUCT.md). The rk maintainers keep an eye on\nissues and pull requests, but you can also report any negative conduct to\nlark@rkdev.info.\n\nReleased under the [Apache 2.0 License](LICENSE).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frookie-ninja%2Frk-echo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frookie-ninja%2Frk-echo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frookie-ninja%2Frk-echo/lists"}