A template for generic golang applications.
Using Nix you can create a develop environment with all the tooling required to build this application.
This flake was initialized using a template.
nix flake init --template "github:DeterminateSystems/zero-to-nix#go-dev"
I expanded this to include the additional packages required to build.
You can enter the dev shell with the command nix develop
.
This section will cover all the moving parts of this demo. Each closes one gap for the fully declarative extensible build.
sqlc
is used to build out your database connection and query layers using just regular sql queries.
buf
is the new industry standard when it comes to protobuf generation. protoc
is still used but buf
is more declarative and extensible.
golang-migrate migrate
tool is used for database migrations. Its somewhat overkill for this but nice to show that it can be used along with sqlc
and is easier to manage sql changes than traditional sql scripts.
- Install the following tools.
-
sqlc cli
-
buf cli
-
golang-migrate cli
-
docker and docker-compose
-
make (optional)
-
grpcurl (optional for testing grpc server)
- Setup
.env
file - nothing special just to setup db creds.
export DB_HOST=localhost
export DB_PASSWORD=your_password
export DB_USER=your_username
export DB_NAME=golang_app
Note: the following are not needed if cloning this repo but ill cover for completeness. If you've cloned continue at build section.
- Initialize the go module.
go mod init github.com/alexander-bergeron/go-app-tmpl
- Initialize Docker files.
see file contents for further explanation
-
Dockerfile.server
builds the golang server executable. -
compose.yml
is the docker-compose file for orchestration.
- Initialize migrations
migrate create -ext sql -dir migrations -seq init
This creates your migrations directory and creates two empty files, init.up and init.down.
-- init.up
-- Create the users table
CREATE TABLE users (
user_id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(50) NOT NULL UNIQUE,
first_name VARCHAR(100),
last_name VARCHAR(100)
);
INSERT INTO users (username, email, first_name, last_name) VALUES
('Cow31337Killer', '[email protected]', 'Cow', 'Killer'),
('Durial321', '[email protected]', 'Durial', '321'),
('BigRedJapan', '[email protected]', 'BigRed', 'Japan');
-- init.down
DROP TABLE IF EXISTS users;
- Initialize
sqlc.pgx.yaml
.
see file contents for further explanation
- Initialize
buf
files.
see file contents for further explanation
make build
-
This will generate the grpc protobuf code, the migrate directory with init files, and the sqlc.pgx.yaml code.
-
After build completes, manually update swagger.json with host and schemes.
"info": {
"title": "proto/user/v1/user.proto",
"version": "version not set"
},
"host": "localhost:8080", # add this line
"schemes": ["https"], # add this line
"tags": [
{
"name": "UserService"
}
],
go mod tidy
- Updates all your deps.
make gen-certs
- Creates cert files for tls.
-
start docker daemon.
-
make up
- Runs docker compose.
-
make test-get-grpc
- test grpc client call -
make test-get-rest
- test grpc-gateway -
make test-post-grpc
- posts a new test user to the API -
Navigate to
localhost:3000
for a webserver displaying all users with form input for a new user - built with htmx -
Navigate to
localhost:8081
for a swagger page - Note: you will need to add the generatedca.crt
to your browser for swagger to work.
Serving over TLS takes various steps.
-
creating the certs - see Makefile
-
Baking ca cert into swagger ui image
-
updating browser to recognize your custom ca - import the ca.crt
-
Determine how to set host automatically for swagger page rather than manual change after generation.
-
Setup CORS so its not hard coded.
-
setup static css and js
-
test to see if air works in container - reference