This project is a sandbox for learning Go, oapi-codegen, and Swagger. The goal is to understand Go conventions regarding naming and code organization. I intend to use this repository as a boilerplate/starter template for future projects.
- Generate api
go generate ./...in the project root - Start app
go run cmd/main.goin the project root - Start app with debug-server
go run -tags debug cmd/main.go - Swagger-ui
http://localhost:3000/swagger/ - Debug
http://localhost:8081/debug
.
├── README.md
├── cmd
│ └── main.go # Entry point for the applications
├── go.mod
├── go.sum
├── internal
│ ├── api
│ │ ├── api.gen.go # Generated by go generate ./...
│ │ ├── config.yml # Config for generating api.gen.go
│ │ ├── generate.go # Config for generating api.gen.go
│ │ └── oapi_codegen.yml # Api-configuration
│ ├── application
│ │ └── app.go # Initializes the app with Db and logger
│ ├── debug
│ │ ├── debug.go # Starts debug-server (with -tags debug)
│ │ └── debugDisabled.go # Emtpty code for run without debug-server
│ ├── domain
│ │ └── user.go # Defines domain-objects
│ ├── handlers
│ │ ├── check.go # Handles check functions
│ │ ├── servers.go # Handles Serverinterface from api.gen.go
│ │ └── user.go # Handles user functions
│ ├── repository
│ │ └── maprepo.go # Database repository
│ └── service
│ │ └── user.go # User services - domain logic
│ └── util
│ └── envvars.go # Getters for environment-variables
└── swagger
└── index.html # html for swagger
The file oapi_codegen.yml includes both api's and components. It defines a health endpoint and a user object including crud endpoints for it. The generate.go and config.yml-files enables the creation of api.gen.go from oapi_codegen.yml, using the command go generate ./... The api.gen.go file contains a User-struct, endpoints and a ServerInterface
There are three handlers in the handlers package, servers.go, check.go and user.go
- servers contains implementations of the ServerInterface created in api.gen.go. It also defines the requirements (interfaces) towards the check and user-handlers and calls them
- check implements the CheckHandler-interface defined in servers.go and performs the actual check.
- user implements the UserHandler-interface defined in servers.go, and defines a UserService-interface. It makes the syntactic checks of the incoming calls and then calls on the UserService-interface
Here a domain.User is defined, to make the app-logic independent of future changes in the api-spec. There is also a list of predefined error-messages
The user.go implements the UserService-interface and defines the DbInterface. It calls the DbInterface-functions, and performs the logical checks (business rules etc.) From the service and down the domain.User is used, which means that the service converts between api.User and domain.User when communicating with the handlers. Results from the Db-interaction and logical checks are sent back to the handlers
The implementation of tha DbInterface is a map[string]domain.User. To be replaced by the persistence layer of your choice.
For the swagger part, the index.html and the yaml-file that was used to create the api is needed. The yaml-file is aliased in the function setupFiber in main.go to openapi.yaml.
Use -tags debug to start a debug-server. The purpouse is to show what's in the MapRepository. The debugport can be set in .env with variablename DEBUGPORT, otherwise just use the fallback port 8081, then no config is needed. Use localhost:8081/debug to show what's in the MapRepository. Add new repositories, tables as needed. If this feature is unneccesary, just remove the debug folder and the row debug.StartDebugServer(app.Repo) from the main.go