Go Server/API boilerplate using best practices DDD CQRS ES gRPC

🧰 Golang API Starter Kit

Build Status Test Go Report Card codecov license baker sponsor

logo

Go Server/API boilerplate using best practices, DDD, CQRS, ES, gRPC.

Table of Contents

πŸ“– ABOUT

The main purpose of this project is to provide boilerplate project setup using best practices, DDD, CQRS, ES, gRPC. Featuring kubernetes for both development and production environments. Allowing to work with environment reflecting production one, allowing to reduce any misconfigurations.

This is mono-repository of many services such as authentication or user domain. Each service has it own code base with exception of shared packages to simplify things for this boilerplate. Services communicate witch each other using gRPC. Each service might expose HTTP API for external communication or/and gRPC.

This project setup should reduce the time spent on environment configuration for the whole kubernetes cluster and/or each of microservice. Extracting each of services to own repository or keeping it as mono-repo should be a matter of preference.

Please look for comments like @TODO and @FIXME to better understand things than need attention.

Web UI example (React)

This boilerplate includes simple Web UI to demonstrate example interaction with API. Once deployed and hosts are set please visit https://api.go-api-boilerplate.local to access UI.

Web UI

Key concepts:

  1. Rest API
  2. Docker
  3. Kubernetes
  4. Helm chart
  5. Terraform
  6. gRPC
  7. Domain Driven Design (DDD)
  8. CQRS
  9. Event Sourcing
  10. Hexagonal, Onion, Clean Architecture
  11. oAuth2

Worth getting to know packages used in this boilerplate:

  1. gorouter
  2. message-bus
  3. gollback
  4. shutdown
  5. pubsub
  6. pushpull
  7. gocontainer

πŸ“š DOCUMENTATION

🏫 EXAMPLE

Quick start

Localhost alias

Edit /etc/hosts to add localhost alias

➜ go-api-boilerplate git:(master) cat /etc/hosts
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 go-api-boilerplate.local api.go-api-boilerplate.local maildev.go-api-boilerplate.local mysql.go-api-boilerplate.local

Build release

Local image

make docker-build BIN=auth
make docker-build BIN=migrate
make docker-build BIN=user
make docker-build BIN=web

GitHub Package Registry

Creating tag with metadata will trigger github workflow and publish docker image to GitHub Package Registry.

Tag v1.0.0+user will trigger build for user service releasing 1.0.0 docker image tag. you can create release for all services in cmd directory.

v1.0.0+auth
v1.0.0+user
v1.0.0+web
v1.0.0+migrate

Replace image details in main.yaml

  image:
-    repository: go-api-boilerplate-user
+    repository: docker.pkg.github.com/vardius/go-api-boilerplate/go-api-boilerplate-user
-    tag: latest
+    tag: 1.0.0
    pullPolicy: IfNotPresent

repeat for all services and migrate init containers.

Private Registry

Log in to Docker

docker login

Copy docker config

cp ~/.docker/config.json ./k8s/.docker/config.json

Verify config.json

Deploy release

make terraform-install

Destroy

make terraform-destroy

If persistent volume is stack in terminating, this happens when persistent volume is protected. You should be able to cross verify this:

kubectl describe pvc PVC_NAME --namespace=go-api-boilerplate | grep Finalizers

Output:
Finalizers:    [kubernetes.io/pvc-protection]

You can fix this by setting finalizers to null using kubectl patch:

kubectl patch pvc PVC_NAME --namespace=go-api-boilerplate -p '{"metadata":{"finalizers": []}}' --type=merge

Build tags

Build flags are used for different persistence layers. Please see services.go file for details. Provided layers are mysql, mongo and memory. If desired in similar way new layer can be easily added, following given patter.

go build -tags=persistence_mysql

Available build tags

  • persistence_mysql (mysql service container)
  • persistence_mongodb (mongodb service container)

Important persistence layer defaults to memory if no flag is provided (Docker image sets persistence_mysql flag), see each service Dockerfile for details.

Domain

Dispatching command

Send example JSON via POST request

curl -d '{"email":"[email protected]"}' -H "Content-Type: application/json" -X POST https://api.go-api-boilerplate.local/users/v1/dispatch/user/user-register-with-email --insecure

View

Public routes

Get user details https://api.go-api-boilerplate.local/users/v1/34e7ed39-aa94-4ef2-9422-401bba9fc812

{"id":"34e7ed39-aa94-4ef2-9422-401bba9fc812","email":"[email protected]"}

Get list of users https://api.go-api-boilerplate.local/users/v1?page=1&limit=10

{"page":1,"limit":20,"total":1,"users":[{"id":"34e7ed39-aa94-4ef2-9422-401bba9fc812","email":"[email protected]"}]}

Protected routes

Access protected route using auth token https://api.go-api-boilerplate.local/users/v1/me.

{"code": "401","message": "Unauthorized"}

Request access token for user

curl -d '{"email":"[email protected]"}' -H "Content-Type: application/json" -X POST https://api.go-api-boilerplate.local/users/v1/dispatch/user/user-request-access-token --insecure

Get your access token from mail catcher https://maildev.go-api-boilerplate.local.

Access protected route using auth token https://api.go-api-boilerplate.local/users/v1/me?authToken=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJyXHUwMDE277-977-977-977-9IiwiZXhwIjoxNTU5NjEwOTc2LCJzdWIiOiIzNGU3ZWQzOS1hYTk0LTRlZjItOTQyMi00MDFiYmE5ZmM4MTIifQ.pEkgtDAvNh2D3Dtgfpu4tt-Atn1h6QwMkDhz4KpgFxNX8jE7fQH00J6K5V7CV063pigxWhOMMTRLmQdhzhajzQ

{"id":"34e7ed39-aa94-4ef2-9422-401bba9fc812","email":"[email protected]"}

πŸ’² Sponsoring

πŸš€ Contributing

Want to contribute ? Feel free to send pull requests!

Have problems, bugs, feature ideas? We are using the github issue tracker to manage them.

πŸ‘¨πŸ»β€πŸ’»πŸ‘©πŸΎβ€πŸ’» Core Team:


RafaΕ‚ Lorenz

Marin Kirkov

πŸ‘₯ Backers

Support us with a monthly donation and help us continue our activities.

πŸ₯‡ Sponsors

Proudly sponsored by Open Collective sponsors.

πŸ“œ License

Comments
  • "x-www-form-urlencoded" to "json" conversion middleware for gorouter

    I am currently working on porting a "x-www-form-urlencoded" to "json" conversion middleware for gorouter: https://github.com/mar1n3r0/go-json-rest-middleware-formjson.

    I will open a separate topic about that if you don't mind and think that it will be of significant use to the boilerplate overall.

    Originally posted by @mar1n3r0 in https://github.com/vardius/go-api-boilerplate/pull/58#issuecomment-597015340

  • 404 page not found/503 Service Temporary Unavailable

    404 page not found/503 Service Temporary Unavailable

    Followed that setup: https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/

    Browser request: https://go-api-boilerplate.local/users?page=1&limit=10

    Browser response: 404 page not found/503 Service Temporary Unavailable

    HTTP response:

    curl go-api-boilerplate.local
    <html>
    <head><title>308 Permanent Redirect</title></head>
    <body>
    <center><h1>308 Permanent Redirect</h1></center>
    <hr><center>openresty/1.15.8.2</center>
    </body>
    </html>
    
    

    HTTPS response:

    curl https://go-api-boilerplate.local/users?page=1&limit=10
    [1] 9013
    [mar1n3r0@marin-airhead go-api-boilerplate]$ curl: (60) SSL certificate problem: unable to get local issuer certificate
    More details here: https://curl.haxx.se/docs/sslcerts.html
    
    curl failed to verify the legitimacy of the server and therefore could not
    establish a secure connection to it. To learn more about this situation and
    how to fix it, please visit the web page mentioned above.
    
  • Init containers migration failing

    Init containers migration failing

    I have locked migrate/migrate to v4.7.1 and managed to get the specific errors from the init containers:

    error: open /migrations/auth: no such file or directory
    error: open /migrations/user: no such file or directory
    

    The migrations directory is not copied to the final image. Expected migration files for example auth service https://github.com/vardius/go-api-boilerplate/blob/20fe02936f82db7d723f33ebfbc69092dc42226d/helm/app/values.yaml#L184 Copied files are: https://github.com/vardius/go-api-boilerplate/blob/20fe02936f82db7d723f33ebfbc69092dc42226d/cmd/auth/Dockerfile#L38 Doing so should solve the issue, with migrations

    FROM scratch
    COPY --from=buildenv /go/bin/app /go/bin/app
    + COPY --from=buildenv /app/migrations/"$BIN" /migrations/"$BIN"
    ENTRYPOINT ["/go/bin/app"]
    

    This needs to be done for both auth and user service.

    Originally posted by @vardius in https://github.com/vardius/go-api-boilerplate/issues/22#issuecomment-567684300

  • Kubernetes 1.16 API breaking changes

    Kubernetes 1.16 API breaking changes

    Hello and thanks for the fantastic boilerplate. I am using it for a starter point for my own project and currently testing with minikube locally. I will try to summarize my discoveries so far:

    1. After the breaking changes with apiVersion with kubernetes 1.16 onwards some of the helm charts don't work for me since they were not updated according to the guidelines. See: https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/ Example after running helm make-install originally:
    helm install --name go-api-boilerplate --namespace go-api-boilerplate helm/app/
    Error: validation failed: unable to recognize "": no matches for kind "Deployment" in version "extensions/v1beta1"
    make: *** [Makefile:64: helm-install] Error 1
    
    

    As you can see with the current script it's impossible to see which chart specifically failed. Do you observe the same behavior by any chance ? 2. Because of that I have heavily modified the helm scripts to actually get latest packages from helm hub rather than use the archives included in the repo. 3. Even some of the latest stable charts are not updated as of yet to 1.16 guidelines. Namely magic-namespace and heapster so far. Due to this I have disabled those for the time being 4. Since I am installing the charts one by one and not as one whole package like the original I am facing some unexpected issues. Mostly some kubernetes services names don't match nginx ingress definitions. For example: go-api-boilerplate.user, go-api-boilerplate.auth etc... I see them as microservice-user, microservice-auth in my services list.

    As soon as I have some decent workaround for the hardcoded charts I can create a PR, meanwhile I would appreciate if you had some ideas how to make those dependencies more flexible instead of tgz packages in the repo.

    Originally posted by @mar1n3r0 in https://github.com/vardius/go-api-boilerplate/issues/15#issuecomment-566704265

  • Input validation, sanitizing and form/multiform/files support, OAuth2 logic

    Input validation, sanitizing and form/multiform/files support, OAuth2 logic

    Continuing the topic here.

    Because we are using CQRS patter, the way I think validation should be done is for value objects to validate incoming data.

    So technically for example here:

    // ChangeEmailAddress command
    type ChangeEmailAddress struct {
    	ID    uuid.UUID `json:"id"`
    	Email string    `json:"email"`
    }
    

    each property should be a value object (VO), that validates data

    // ChangeEmailAddress command
    type ChangeEmailAddress struct {
    	ID    uuid.UUID `json:"id"`
    	Email vo.Email  `json:"email"`
    }
    

    this way you ensures that data passed to the events always conforms to the rules, i dont mind having different validation system that we could for example use in our VOs

    but anyway lets first fix/merge current open prs and then we will consider other futures. scopes are good idea, i am not sure but i dont think we should need to do much here, it should work out of box with current oauth2 implementation

    Originally posted by @vardius in https://github.com/vardius/go-api-boilerplate/issues/39#issuecomment-570094391

    Maybe it's better to do the sanitizing and validation one step before. If we ensure this happens in BuildCommandDispatchHandler where we still have the request instead of doing it later in the NewCommandFromPayload then the CQRS structs will always get the sanitized/validated data. The earlier the better, less data moving down the pipe.

    This has the advantage that we can reuse a mature open-source package which has additional benefits like adding form/multiform/files support.

    What do you think @vardius ?

    Edit: That looks like a great candidate for both json, text/plain and form data altogether:

    govalidator

    So far I got my eyes on: albrow/forms as the validation happens on the http.Request level.

    But since last update was 2 years ago and it's not migrated to using modules we can take a look at other options as well: awesome-go forms

    The previously mentioned ozzo-validation seems to be tailored to validation of value objects level so not really suited for use with the http package directly. This kind of takes it out of the equation for now I guess.

  • Value objects

    Value objects

    I have used github.com/asaskevich/govalidator because it provides primitive functions such as IsEmail

    Haven't tested if it actually works, just a draft of how i think it should look like

    using value objects for validations has some advantages as:

    • one source of truth for rules (value object)
    • validates both commands and events
    • ensures events are always valid (for example when one has to replay event store to rebuild state)
    • because we use cqrs there is no need for another layer
  • Remove deprecated magic-namespace

    Remove deprecated magic-namespace

    magic-namespace deprecation notice

    Note that this chart manages namespaces and also Helm 2 Tiller instances within those namespaces. Helm 3 releases are scoped to namespaces and therefore cannot create namespaces. Helm 3 also does not utilize the Tiller component. Helm 3, therefore, is both incapable of installing this chart and has no practical need for this chart to begin with. With this being the case, maintainers have no intention of remediating this chart's incompatibilities with Helm 3, as that would undermine the chart's ongoing usefulness to Helm 2 users without deriving any benefit to Helm 3 users.

    In conclusion, consider this chart to be deprecated, with updates and support ending on the same schedule as Helm 2 itself.

    I guess with that in mind we can completely remove magic-namespace.

    Originally posted by @mar1n3r0 in https://github.com/vardius/go-api-boilerplate/issues/46#issuecomment-570610144

  • (WIP pending stable chart to be updated to 2.0.0) Kubernetes dashboard per namespace

    (WIP pending stable chart to be updated to 2.0.0) Kubernetes dashboard per namespace

    kubernetes-dashboard-per-namespace

    Originally posted by @mar1n3r0 in https://github.com/vardius/go-api-boilerplate/issues/27#issuecomment-568914308

    We should update our kubernetes-dashboard chart values and install it only for our namespace

  • request-access-token - oauth2: cannot fetch token: 404 Not Found/400 bad request

    request-access-token - oauth2: cannot fetch token: 404 Not Found/400 bad request

    DEBUG: [EventBus|Subscribe]: user.AccessTokenWasRequested {"id":"f610c09b-d7c6-4311-9573-cd841dd4a819","email":"[email protected]"}
    2019/12/27 16:43:57.982291 DEBUG: [EventBus|Subscribe]: user.AccessTokenWasRequested {"id":"f610c09b-d7c6-4311-9573-cd841dd4a819","email":"[email protected]"}
    2019/12/27 16:43:57 [EventHandler] {"id":"f610c09b-d7c6-4311-9573-cd841dd4a819","email":"[email protected]"}
    2019/12/27 16:43:57.991235 DEBUG: [EventBus|Subscribe]: user.AccessTokenWasRequested {"id":"f610c09b-d7c6-4311-9573-cd841dd4a819","email":"[email protected]"}
    2019/12/27 16:43:58 [EventHandler] Error: oauth2: cannot fetch token: 404 Not Found
    Response: 404 page not found
    

    That was fixed by #43 Add /v1 prefix to oauth2Config

    The next one happening is:

    user_logs:

    2019/12/31 20:44:40.629628 DEBUG: [EventBus|Publish]: user.AccessTokenWasRequested {"id":"d53836de-23d2-45a6-abb0-87f5abea8a2f","metadata":{"type":"user.AccessTokenWasRequested","stream_id":"00000000-0000-0000-0000-000000000000","stream_name":"user.User","stream_version":0,"occurred_at":"2019-12-31T20:44:40.628333849Z"},"payload":{"id":"00000000-0000-0000-0000-000000000000","email":""}}
    2019/12/31 20:44:40.645071 INFO: [Request|End]: 7d0d9965-6268-45d7-9ceb-79e98b284ee6 : (0) : POST /v1/dispatch/request-user-access-token -> 172.17.0.8:45394 (23.73608ms)
    2019/12/31 20:44:40.646782 DEBUG: [EventBus|Subscribe]: user.AccessTokenWasRequested {"id":"00000000-0000-0000-0000-000000000000","email":""}
    2019/12/31 20:44:40 [EventHandler] {"id":"00000000-0000-0000-0000-000000000000","email":""}
    2019/12/31 20:44:40 [EventHandler] Error: oauth2: cannot fetch token: 400 Bad Request
    Response: {"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed"}
    

    auth_logs:

    2019/12/31 20:57:15.329019 ERROR: oAuth2 Server response error: invalid_client
    &{invalid_client 0 Client authentication failed  401 map[]}
    2019/12/31 20:57:15.331306 INFO: [Request|End]: 4a8f5593-ba15-444e-844e-6a7c381bedd1 : (0) : POST /v1/token -> 172.17.0.15:56618 (5.698101ms)
    2019/12/31 20:57:15.332723 INFO: [Request|Start]: 490cbe9b-dd4c-43de-92eb-5abbb59cea66 : (0) : POST /v1/token -> 172.17.0.15:56618
    2019/12/31 20:57:15.333062 ERROR: oAuth2 Server response error: invalid_request
    &{invalid_request 0 The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed  400 map[]}
    
  • panic: interface conversion

    panic: interface conversion

    panic: interface conversion: interface {} is user.WasRegisteredWithEmail, not *user.WasRegisteredWithEmail

    goroutine 65 [running]: github.com/vardius/go-api-boilerplate/cmd/user/internal/application/eventhandler.WhenUserWasRegisteredWithEmail.func1({0xada780, 0x4000283470}, 0x4000200880) /app/cmd/user/internal/application/eventhandler/when_user_was_registered_with_email.go:22 +0x374 github.com/vardius/go-api-boilerplate/pkg/eventbus/memory.(*eventBus).Subscribe.func1({0xada780, 0x4000283470}, 0x4000200880, 0x40002d6840) /app/pkg/eventbus/memory/event_bus.go:107 +0xe4 reflect.Value.call({0x7a6480, 0x400045d200, 0x13}, {0x8836e1, 0x4}, {0x400011f3e0, 0x3, 0x4}) /usr/local/go/src/reflect/value.go:543 +0x590 reflect.Value.Call({0x7a6480, 0x400045d200, 0x13}, {0x400011f3e0, 0x3, 0x4}) /usr/local/go/src/reflect/value.go:339 +0x8c github.com/vardius/message-bus.(*messageBus).Subscribe.func1(0x400045d220) /go/pkg/mod/github.com/vardius/[email protected]/bus.go:60 +0x74 created by github.com/vardius/message-bus.(*messageBus).Subscribe /go/pkg/mod/github.com/vardius/[email protected]/bus.go:58 +0x278

  • rpc error: code = Unimplemented desc = unknown service

    rpc error: code = Unimplemented desc = unknown service

    Looking for advice... I am getting this when trying to make a gRPC call to a new service cloned from an existing one. Wondering how could this be debugged as readiness and health checks are reporting all ok.

    As far as I understand the gRPC server hasn't registered the service but no errors were reported at the time of starting.

    Suspecting specifically this part: https://github.com/vardius/go-api-boilerplate/blob/0010b2c59e0f671006afef0d720b5c3b3edfdd56/cmd/user/internal/interfaces/grpc/adapter.go#L34

    Curious to know how can we check that it was successfully registered.

    If the service is added to the grpcConnectionMap of a dependent service the output is: gRPC connection is not serving

    It makes me think that there is a network issue on my side since the internal readiness probe works.

    P.S. The code generated in pb.go is identical and complete.

  • Bump express from 4.17.1 to 4.18.2 in /cmd/web

    Bump express from 4.17.1 to 4.18.2 in /cmd/web

    Bumps express from 4.17.1 to 4.18.2.

    Release notes

    Sourced from express's releases.

    4.18.2

    4.18.1

    • Fix hanging on large stack of sync routes

    4.18.0

    ... (truncated)

    Changelog

    Sourced from express's changelog.

    4.18.2 / 2022-10-08

    4.18.1 / 2022-04-29

    • Fix hanging on large stack of sync routes

    4.18.0 / 2022-04-25

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

  • Bump qs from 6.5.2 to 6.5.3 in /cmd/web

    Bump qs from 6.5.2 to 6.5.3 in /cmd/web

    Bumps qs from 6.5.2 to 6.5.3.

    Changelog

    Sourced from qs's changelog.

    6.5.3

    • [Fix] parse: ignore __proto__ keys (#428)
    • [Fix] utils.merge: avoid a crash with a null target and a truthy non-array source
    • [Fix] correctly parse nested arrays
    • [Fix] stringify: fix a crash with strictNullHandling and a custom filter/serializeDate (#279)
    • [Fix] utils: merge: fix crash when source is a truthy primitive & no options are provided
    • [Fix] when parseArrays is false, properly handle keys ending in []
    • [Fix] fix for an impossible situation: when the formatter is called with a non-string value
    • [Fix] utils.merge: avoid a crash with a null target and an array source
    • [Refactor] utils: reduce observable [[Get]]s
    • [Refactor] use cached Array.isArray
    • [Refactor] stringify: Avoid arr = arr.concat(...), push to the existing instance (#269)
    • [Refactor] parse: only need to reassign the var once
    • [Robustness] stringify: avoid relying on a global undefined (#427)
    • [readme] remove travis badge; add github actions/codecov badges; update URLs
    • [Docs] Clean up license text so it’s properly detected as BSD-3-Clause
    • [Docs] Clarify the need for "arrayLimit" option
    • [meta] fix README.md (#399)
    • [meta] add FUNDING.yml
    • [actions] backport actions from main
    • [Tests] always use String(x) over x.toString()
    • [Tests] remove nonexistent tape option
    • [Dev Deps] backport from main
    Commits
    • 298bfa5 v6.5.3
    • ed0f5dc [Fix] parse: ignore __proto__ keys (#428)
    • 691e739 [Robustness] stringify: avoid relying on a global undefined (#427)
    • 1072d57 [readme] remove travis badge; add github actions/codecov badges; update URLs
    • 12ac1c4 [meta] fix README.md (#399)
    • 0338716 [actions] backport actions from main
    • 5639c20 Clean up license text so it’s properly detected as BSD-3-Clause
    • 51b8a0b add FUNDING.yml
    • 45f6759 [Fix] fix for an impossible situation: when the formatter is called with a no...
    • f814a7f [Dev Deps] backport from main
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

  • Bump decode-uri-component from 0.2.0 to 0.2.2 in /cmd/web

    Bump decode-uri-component from 0.2.0 to 0.2.2 in /cmd/web

    Bumps decode-uri-component from 0.2.0 to 0.2.2.

    Release notes

    Sourced from decode-uri-component's releases.

    v0.2.2

    • Prevent overwriting previously decoded tokens 980e0bf

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.1...v0.2.2

    v0.2.1

    • Switch to GitHub workflows 76abc93
    • Fix issue where decode throws - fixes #6 746ca5d
    • Update license (#1) 486d7e2
    • Tidelift tasks a650457
    • Meta tweaks 66e1c28

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.1

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

  • [question] domain pollution

    [question] domain pollution

    Hello @vardius

    Thank you for sharing this library, it is very helpful in many regards!

    My question is about your choice of appending the metadata in the aggregate itself. Eg.

    func (u *User) trackChange(ctx context.Context, event *domain.Event) error {
    	var meta domain.EventMetadata
    	if i, hasIdentity := identity.FromContext(ctx); hasIdentity {
    		meta.Identity = i
    	}
    	if m, ok := metadata.FromContext(ctx); ok {
    		meta.IPAddress = m.IPAddress
    		meta.UserAgent = m.UserAgent
    		meta.Referer = m.Referer
    	}
    	if !meta.IsEmpty() {
    		event.WithMetadata(&meta)
    	}
    
    	u.changes = append(u.changes, event)
    	u.version++
    
    	return nil
    }
    

    Seeing the UserAgent or IP exposed in the aggregate feels a bit like pollution of a domain with application/infra data. I understand that the aggregate essentially proxies this data from the command handler, which usually is acceptable practice, as aggregate is not making use of that data.

    I am wondering if you would not mind sharing your thoughts as to why you chose to enrich the event in the aggregate as opposed to eg. in the aggregate repository implementation.

    Thanks again for sharing!

  • terraform apply

    terraform apply

    I tried make terraform-install and result is

    cd k8s \
      kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager.crds.yaml \
    terraform init \
    terraform apply \
      terraform output -raw templates | kubectl apply -f -
    error: no objects passed to apply
    make: *** [Makefile:66: terraform-install] Error 1
    

    when I try command by comand then by kubectl apply is result this...

    
    Error: Post "http://localhost/api/v1/namespaces": dial tcp 127.0.0.1:80: connect: connection refused
    β”‚ 
    β”‚   with kubernetes_namespace.main,
    β”‚   on k8s-namespace.tf line 1, in resource "kubernetes_namespace" "main":
    β”‚    1: resource "kubernetes_namespace" "main" {
    β”‚ 
    β•΅
    β•·
    β”‚ Error: Post "http://localhost/apis/storage.k8s.io/v1/storageclasses": dial tcp 127.0.0.1:80: connect: connection refused
    β”‚ 
    β”‚   with kubernetes_storage_class.mongodb,
    β”‚   on mongodb.tf line 28, in resource "kubernetes_storage_class" "mongodb":
    β”‚   28: resource "kubernetes_storage_class" "mongodb" {
    

    Can you help me? Please

  • Documentation

    Documentation

    If

    1. You have some questions
    2. You had a problem with setup
    3. You had a problem with configuration
    4. You don't know how to do something
    5. Have ideas or propositions
    6. Think something could be explained better/in more details

    Let me know so I can update documentation, allowing other ppl get over same issues faster. Please comment here about your suggestion what should/could be added/updated in the documentation. And I will try to explain or to do it as soon as possible.

Gin-boilerplate - This repository contains boilerplate code of a REST service using Gin (golang) framework.

Boilerplate REST service using Gin web framework (golang) Introduction This repository contains a boilerplate REST API service using Gin web framework

Apr 28, 2022
Gin-boilerplate - Gin boilerplate preconfigured with basic rest api features

Gin Boilerplate Build apis with gin faster with this template Features Validatio

Jun 24, 2022
Sample Go REST API implementation with DDD using Clean Architecture.

This layer is a part developed for client-side (mobile, web, etc.) applications to access our domain. It will forward the requests from this layer to the application layer and expose the response it receives from the application layer.

Jan 3, 2023
Dating-server - Go (Golang) API REST Template/Boilerplate with Gin Framework

go-rest-template Go (Golang) API REST Template/Boilerplate with Gin Framework 1.

Apr 3, 2022
Best lightweight, powerful and really fast Api with Golang (Fiber, REL, Dbmate) PostgreSqL

Best lightweight, powerful and really fast Api with Golang (Fiber, REL, Dbmate) PostgreSqL

Dec 26, 2021
Golang Simple Boilerplate with Gofiber & Gorm

Golang Simple Boilerplate with Gofiber & Gorm Boilerplate Structure config/ controller/ entity/ exception/ helper/ middleware/ model/ repository/ seed

May 11, 2022
Go-gin-mongo-api - A backend RESTful API built using golang, gin and mongoDB

go-gin-mongo-API This is a RESTful backend API which is developed using the gola

Jul 19, 2022
Api-go-gin-viper - Simple representaion on how to implement CRUD functionality in API using Go programming language

Simple API implementaion in Go To Get Started Clone repo Run the command to clon

Feb 18, 2022
GRPC Basic Implementation For Golang

GRPC Basic Implementation What is Remote Procedure Call In your CLIENT code, It looks like you're just calling a function directly on SERVER For examp

Nov 23, 2021
The source code for workshop Scalable architecture using Redis as backend database using Golang + Redis

The source code for workshop Scalable architecture using Redis as backend database using Golang + Redis

Sep 23, 2022
A simple command line tool using which you can skip phone number based SMS verification by using a temporary phone number that acts like a proxy
A simple command line tool using which you can skip phone number based SMS verification by using a temporary phone number that acts like a proxy

Fake-SMS A simple command line tool using which you can skip phone number based SMS verification by using a temporary phone number that acts like a pr

Dec 31, 2022
An RRDtool api server that exports a subset of rrdtool commands over http(s).

rrdsrv An RRDtool api server that exports a subset of rrdtool commands over http(s). Be sure to checkout the grafana plugin. Demo video. Usage Usage o

Dec 7, 2022
Instagram Backend HTTP REST API using GO Lang and Mongo DB

Instagram Backend HTTP REST API using GO Lang and Mongo DB Project for Appointy Summer Internship . Project built within 25 hrs, with no prior knowled

Oct 10, 2021
A Golang REST API to handle users and posts for a simple instagram backend. Uses MongoDB as the database. Tested using golang-testing and Postman.
A Golang REST API to handle users and posts for a simple instagram backend. Uses MongoDB as the database. Tested using golang-testing and Postman.

A Golang REST API to handle users and posts for a simple instagram backend. Uses MongoDB as the database. Tested using golang-testing and Postman.

Oct 10, 2021
REST API of Instagram's functionalities; developed using GO (and Mongo).
REST API of Instagram's functionalities; developed using GO (and Mongo).

Instagram-backend-api REST API of Instagram's functionalities; developed using GO (and Mongo). Constraints: Complete API has been developed using Go M

Oct 9, 2021
Restful API example with using go and gin framework

simple device api Simple Device API is really simple and concise to show how easy to implement a Restful Service with using Golang. It uses gin framew

Nov 18, 2021
Rest API Product using Postgre as RDBMS
Rest API Product using Postgre as RDBMS

API Specification General info This is Rest API Product using Postgre as RDBMS. Tools? Please read the go.mod file. DDL CREATE TABLE products ( id bp

Nov 5, 2021
GO API with Gin Gonic with postgresql using gorp

GO API with Gin Gonic with postgresql using gorp Tips: Make sure you have project in src folder of $GOPATH Also, iniitalize go mod init project-name a

Jul 28, 2022
Check the report history of any IP address to see if anyone else has reported malicious activities using API

abuseip Check the report history of any IP address to see if anyone else has reported malicious activities using API by abuseipdb.com. Installation $

Nov 13, 2021