Giter VIP home page Giter VIP logo

modern-go-application's Introduction

Modern Go Application

Mentioned in Awesome Go Go Report Card go.dev reference

GitHub Workflow Status CircleCI Gitlab

Go application boilerplate and example applying modern practices

This repository tries to collect the best practices of application development using Go language. In addition to the language specific details, it also implements various language independent practices.

Some of the areas Modern Go Application touches:

  • architecture
  • package structure
  • building the application
  • testing
  • configuration
  • running the application (eg. in Docker)
  • developer environment/experience
  • telemetry

To help adopting these practices, this repository also serves as a boilerplate for new applications.

Features

First steps

To create a new application from the boilerplate clone this repository (if you haven't done already) into your GOPATH then execute the following:

chmod +x init.sh && ./init.sh
? Package name (github.com/sagikazarmark/modern-go-application)
? Project name (modern-go-application)
? Binary name (modern-go-application)
? Service name (modern-go-application)
? Friendly service name (Modern Go Application)
? Update README (Y/n)
? Remove init script (y/N) y

It updates every import path and name in the repository to your project's values. Review and commit the changes.

Load generation

To test or demonstrate the application it comes with a simple load generation tool. You can use it to test the example endpoints and generate some load (for example in order to fill dashboards with data).

Follow the instructions in etc/loadgen.

Inspiration

See INSPIRATION.md for links to articles, projects, code examples that somehow inspired me while working on this project.

License

The MIT License (MIT). Please see License File for more information.

modern-go-application's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

modern-go-application's Issues

Add badges

  • Golang CI
  • Go Report Card
  • Go Doc
  • Build badges (Travis, Circle)

Better support for multiple binaries

Currently the project does not support multiple binary use cases well:

  • make only builds one package
  • docker only builds one app
  • docker only copies one binary

Cannot execute init.sh

Using the latest go version and the latest main pull, I get the following error:

$ ./init.sh 
? Package name (/home/oipo/Programming/chargepoint/go/modern-go-application) nrg-playground
? Project name (nrg-playground) 
? Binary name (nrg-playground) 
? Application name (nrg-playground) 
? Friendly application name (Nrg Playground) 
? Update README (Y/n) 
? Remove init script (y/N) 
mv: cannot stat '.idea/project.iml': No such file or directory
./init.sh: line 36: .idea/modules.xml.new: No such file or directory
mv: cannot stat '.idea/modules.xml.new': No such file or directory
./init.sh: line 36: .idea/runConfigurations/All_tests.xml.new: No such file or directory
mv: cannot stat '.idea/runConfigurations/All_tests.xml.new': No such file or directory
./init.sh: line 36: .idea/runConfigurations/Debug.xml.new: No such file or directory
mv: cannot stat '.idea/runConfigurations/Debug.xml.new': No such file or directory
./init.sh: line 36: .idea/runConfigurations/Integration_tests.xml.new: No such file or directory
mv: cannot stat '.idea/runConfigurations/Integration_tests.xml.new': No such file or directory
./init.sh: line 36: .idea/runConfigurations/Tests.xml.new: No such file or directory
mv: cannot stat '.idea/runConfigurations/Tests.xml.new': No such file or directory
./init.sh: line 36: .vscode/launch.json.new: No such file or directory
mv: cannot stat '.vscode/launch.json.new': No such file or directory
mv: cannot stat 'cmd/modern-go-application': No such file or directory
find: ‘.gen’: No such file or directory

Some violations of CodeReviewComments

  1. Repeatation
    • Package helloworld contains a function NewHelloWorld.
    • So the client would initialize the HelloWorld type as helloworld.NewHelloWorld which is simply repeatation of the fact that helloworld package contains a HelloWorld and is not recommended Package Names
    • This should instead be helloworld.New()
  2. Interfaces
    • Package helloworld contains an interface HelloWorld and function NewHelloWorld returns this interface type instead of concrete type. Interfaces on implementor side as an abstraction has no meaning
    • Package helloworld should contain a concrete type HelloWorld which is returned by helloworld.New function as recommended here
    • Clients who need to use features of HelloWorld type can define interfaces with only the features they really need and inject instance of HelloWorld as an implementation.

Lacking documentation

I would like to use this template for my application, however there is no getting started guide or explanations regarding the proper use and extension of this template.

A Getting Started document and a simple overview of the design of the application would really go great lengths in making this more usable IMO.

configFileNotFound bug?

I was just reviewing the code, and I found a part that looks a little suspect..

https://github.com/sagikazarmark/modern-go-application/blob/master/cmd/modern-go-application/main.go?ts=4#L89

if ReadInConfig does not return an error, then configFileNotFound would be false, right? since the type assert from nil to viper.ConfigFileNotFoundError would fail?

err := v.ReadInConfig()
_, configFileNotFound := err.(viper.ConfigFileNotFoundError)
if !configFileNotFound {
	emperror.Panic(errors.Wrap(err, "failed to read configuration"))
}

# more stuff, including configuring the logger

if configFileNotFound {
	logger.Warn("configuration file not found")
}

it seems like the code will either always panic, or log a warning.

The viper shows the correct way: https://github.com/spf13/viper?ts=4#reading-config-files

if err := viper.ReadInConfig(); err != nil {
    if _, ok := err.(viper.ConfigFileNotFoundError); ok {
        // Config file not found; ignore error if desired
    } else {
        // Config file was found but another error was produced
    }
}

// Config file found and successfully parsed

Additionally, I don't think this is best practice anyway, since a configuration file should not be required if ENV variables are also an alternative. Maybe I'm also reading the code wrong...

Road to 1.0?

This project is a great sandbox for trying out new practices, as well as a great boilerplate for new projects.

As for trying practices, it probably reached a point where the project is "ready", meaning adding new stuff would make it too heavy. Additional service integrations (config) should go into documentation / wiki / website.

Using the project as a boilerplate is not too easy, so this is what I would like to focus on next.

One of the issues is lacking documentation as pointed out in #130.

The other issue is the lack of tooling (code generation, scaffolding).

This is getting better every day in https://github.com/sagikazarmark/mga (especially code generation), but starting a new project is still too hard. So the next step should be a mga new command that creates a new project from the boilerplate. (And we can finally get rid of the crappy init.sh)

Last, but not least we need a better organization of the underlying projects. Right now the boilerplate relies on a few, loosely coupled projects under my account. They need better organization (probably an organization of their own).

Go Buffalo is an excellent example of what I would like to (ideally) achieve with this project.

Add OIDC integration

Why MySQL

Could you please share reasons why you decided to use MySQL for this project?

How to use OpenAPI

There is a folder .gen/api/openapi with generated code. I do not see it's used somewhere. What it is for? Could you please suggest a way how to use it ?

Sync dependencies fails

The application was generated with

? Package name (/home/dima/develop/go-app1) github.com/dmdv/go-app1
? Project name (go-app1) 
? Binary name (go-app1) 
? Application name (go-app1) 
? Friendly application name (Go App1) Modern Go Application
? Update README (Y/n) Y
? Remove init script (y/N) n

When I tried to sync dependencies, I got the following error

go: finding module for package github.com/dmdv/go-app1/internal/app/go-app1
go: finding module for package github.com/dmdv/go-app1/internal/app/go-app1/todo/tododriver
github.com/dmdv/go-app1/cmd/go-app1 imports
	github.com/dmdv/go-app1/internal/app/go-app1: no matching versions for query "latest"
github.com/dmdv/go-app1/cmd/go-app1 imports
	github.com/dmdv/go-app1/internal/app/go-app1/todo/tododriver: no matching versions for query "latest"
github.com/dmdv/go-app1/internal/app/mga imports
	github.com/sagikazarmark/todobackend-go-kit/todo/tododriver imports
	github.com/sagikazarmark/todobackend-go-kit/internal/.generated/api/v1/graphql: malformed import path "github.com/sagikazarmark/todobackend-go-kit/internal/.generated/api/v1/graphql": leading dot in path element
github.com/dmdv/go-app1/internal/app/mga imports
	github.com/sagikazarmark/todobackend-go-kit/todo/tododriver imports
	github.com/sagikazarmark/todobackend-go-kit/internal/.generated/api/v1/rest/go: malformed import path "github.com/sagikazarmark/todobackend-go-kit/internal/.generated/api/v1/rest/go": leading dot in path element

image

And script generation completed with an error

image

The overall impression is that the template has never been tested and too much stuffed with the extra unnecessary functionality

`make up` error during docker-compose up

it looks like this image got removed from the docker hub

Pulling oc-collector (omnition/opencensus-collector:0.1.10)...
ERROR: The image for the service you're trying to recreate has been removed. If you continue, volume data could be lost. Consider backing up your data before continuing.

Is there any tutorial or more detailed document for gokit beginner?

Thanks for this awesome project.

Before I came into this project, I have no experience of gokit.
I want to use this project to learn gokit and start my first gokit project.
Is there any tutorial or more detailed document for gokit beginner to do things like steps of creating new service etc.

Best regards.

Add JWT authentication

Keep the current TODO API for simplicity? Or create a new API with protected resources?

Add Banzai Cloud Spotguide

A Spotguide is a collection of deployable applications and services. A Spotguide is a wizard to create a Git repository, set up CI/CD, create a Kubernetes cluster and deploy the application(s). It’s built upon Helm, but provides additional integration with Banzai Cloud Pipeline.

More information about Spotguides:

https://beta.banzaicloud.io/docs/spotguide/introduction/
https://banzaicloud.com/blog/spotguides-revisited/
https://banzaicloud.com/tags/spotguides/

Banzai Cloud Pipeline is in public beta:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.