Aristat / golang-example-app

Example application
183 stars 72 forks source link
casbin circleci cobra dataloader docker example go golang gorm graphql grpc jaeger mux nats protobuf sql-migrate viper wire zap

golang logo

Golang Example Application

Table of Contents

Overview

This is an example golang application. Commands list:

  1. Daemon - main service
  2. Product service - service that returns Product, an example of gRPC client/server interaction
  3. Health check service - this service is needed to show how convenient to understand on which of the services an error occurred in jaeger
  4. Migrate - commands for migration
  5. JWT - commands for generate JWT token

Package list

Packages which use in this example project

  1. sql-migrate - SQL migrations
  2. wire - dependency Injection
  3. viper - environment configuration
  4. cobra - create commands
  5. cast - easy casting from one type to another
  6. gorm - database ORM
  7. zap - logger
  8. mux - http router
  9. nats-streaming - NATS Streaming System
  10. gqlgen - graphql server library
  11. protobuf - Google's data interchange format
  12. grpc - RPC framework
  13. opentelemetry - OpenTelemetry
  14. jaeger - Jaeger Bindings for Go OpenTelemetry API
  15. casbin - Supports access control
  16. dataloaden - DataLoader for graphql
  17. nats - Golang client for NATS, the cloud native messaging system

Installing

Install the Golang and GO environment

https://golang.org/doc/install

Install Postgresql (if you want to run locally)

Clone repository

git clone git@github.com:Aristat/golang-example-app.git (go get)

Local environment

Install Golang packages without modules

make install

Install database

make createdb

Sql migrations

sql-migrate up

Install Golang dependencies

make dependencies

Generate artifacts(binary files and configs)

make build

Packages for proto generator

https://grpc.io/docs/languages/go/quickstart/#prerequisites

Set APP_WD if you start to use html templates or path to ssh keys or run make test

export APP_WD=go_path to project_path/resources or project_path/artifacts

Docker environment

Generate docker image

DOCKER_IMAGE=golang-example-app TAG=development make docker-image

Run services

Start in local machine

Up jaeger in docker-compose or disable Jaeger(and rebuild binary file) in resources/configs/*.yaml

docker-compose up jaeger

Start daemon (main service)

make start

or

./artifacts/bin daemon -c ./artifacts/configs/development.yaml -d

Start product service

./artifacts/bin product-service -c ./artifacts/configs/development.yaml -d

Start health-check service

./artifacts/bin health-check -c ./artifacts/configs/development.yaml -d

Start in docker

Run this commands

docker-compose rm # Remove previous containers
REMOVE_CONTAINERS=on DOCKER_IMAGE=golang-example-app TAG=development make docker-image # Generate new docker image
docker-compose up

or run script

./scripts/docker-compose-start.sh

Getting Started

Jaeger

http://localhost:16686

Http example with gRPC

http://localhost:9096/products_grpc

Http example with Nats Streaming

http://localhost:9096/products_nats

Http example with graceful shutdown(long request, you can check the server shutdown)

http://localhost:9096/products_slowly

Graphql example with gRPC

Graphql client for testing. End-point http://localhost:9096/query.

Generate JWT for Graphql authorization

./artifacts/bin jwt token --key='./artifacts/keys/local/private_key.pem' --fields='{"sub": "owner", "iss": "test-service"}'

Set JWT token in headers

{
  "Authorization": "bearer token"
}

Example query

query oneUser {
  users {
    one(email: "test@gmail.com") {
      email
      id
    }
  }
}

Example query with data loader

query allProducts {
  products {
    list {
      products {
        id
        productItems {
          id
          name
        }
      }
    }
  }
}

Example mutation

mutation createUser {
  users {
    createUser(email: "test1@gmail.com", password: "123456789") {
      id
      email
    }
  }
}

Testing

➜  make test