Boilerplate for how I like to write a backend web service.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
AJ ONeal 80977071ff update go-gitver 4 miesięcy temu
assets add more CLI options and API scaffolding 4 miesięcy temu
examples add more CLI options and API scaffolding 4 miesięcy temu
internal add more CLI options and API scaffolding 4 miesięcy temu
public add more CLI options and API scaffolding 4 miesięcy temu
tools add more CLI options and API scaffolding 4 miesięcy temu
vendor update go-gitver 4 miesięcy temu
.gitignore add more CLI options and API scaffolding 4 miesięcy temu
.goreleaser.yml add more CLI options and API scaffolding 4 miesięcy temu
.ignore add more CLI options and API scaffolding 4 miesięcy temu
.prettierignore initial commit 5 miesięcy temu
.prettierrc initial commit 5 miesięcy temu
AUTHORS update LICENSE and AUTHORS 5 miesięcy temu
LICENSE initial commit 5 miesięcy temu
README.md add /api/version 4 miesięcy temu
doc.go add more CLI options and API scaffolding 4 miesięcy temu
go.mod update go-gitver 4 miesięcy temu
go.sum update go-gitver 4 miesięcy temu
main.go remove extraneous version newline 4 miesięcy temu

README.md

GoServ

"golang gopher with goggles"

Boilerplate for how I like to write a backend web service

Build

Goreleaser

See https://webinstall.dev/goreleaser

Local-only

goreleaser --snapshot --skip-publish --rm-dist

Publish

# Get a token at https://github.com/settings/tokens
export GITHUB_TOKEN=xxxxxxx

# Remove --snapshot to error on non-clean releases
goreleaser --snapshot --rm-dist

The platform, publish URL, and token file can be changed in .goreleaser.yml:

env_files:
    gitea_token: ~/.config/goreleaser/gitea_token
gitea_urls:
    api: https://try.gitea.io/api/v1/

Manually

git clone ssh://gitea@git.coolaj86.com:22042/coolaj86/goserv.git ./goserv
pushd ./goserv
bash ./examples/build.sh
export GOFLAGS="-mod=vendor"
go mod tidy
go mod vendor
go generate -mod=vendor ./...
go build -mod=vendor -o dist/goserv .

To build for another platform (such as Raspberry Pi) set GOOS and GOARCH`:

GOOS=linux GOARCH=arm64 go build -mod=vendor -o dist/goserv-linux-arm64 .

Run

./dist/goserv run --listen :3000 --trust-proxy --serve-path ./overrides

Examples and Config Templates

The example files are located in ./examples

  • Caddyfile (web server config)
  • .env (environment variables)
  • build.sh
export BASE_URL=https://example.com

Authentication

You can use an OIDC provider or sign your own tokens.

go install -mod=vendor git.rootprojects.org/root/keypairs/cmd/keypairs

# Generate a keypair
keypairs gen -o key.jwk.json --pub pub.jwk.json

Create an Admin token:

# Sign an Admin token
echo '{ "sub": "random_ppid", "email": "me@example.com", "iss": "'"${BASE_URL}"'" }' \
    > admin.claims.json
keypairs sign --exp 1h ./key.jwk.json ./admin.claims.json > admin.jwt.txt 2> admin.jws.json

# verify the Admin token
keypairs verify ./pub.jwk.json ./admin.jwt.txt

Create a User token:

# Sign a User token
echo '{ "sub": "random_ppid", "email": "me@example.com", "iss": "'"${BASE_URL}"'" }' \
    > user.claims.json
keypairs sign --exp 1h ./key.jwk.json ./user.claims.json > user.jwt.txt 2> user.jws.json

# verify the User token
keypairs verify ./pub.jwk.json ./user.jwt.txt

Impersonation can be accomplished by appending the token sub (aka PPID) to the url as ?user_id=.

REST API

All routes require authentication, except for those at /api/public.

Authentication: Bearer <token>

Here's the API, in brief:

Base URL looks like https://example.com/api.

# Demo Mode Only
DELETE /public/reset                                    Drop database and re-initialize

# Public
GET  /public/ping                                       Health Check
POST /public/setup                  <= (none)           Bootstrap

# Admin-only
GET  /admin/ping                                        (authenticated) Health Check

# User
GET  /user/ping                                         (authenticated) Health Check

When you GET anything, it will be wrapped in the result.

Bootstrapping

The first user to hit the /api/setup endpoint will be the admin:

export TOKEN=$(cat admin.jwt.txt)
curl -X POST "${BASE_URL}/api/public/setup" -H "Authorization: Bearer ${TOKEN}"

Then the setup endpoint will be disabled:

curl -X POST "${BASE_URL}/api/public/setup" -H "Authorization: Bearer ${TOKEN}"

GoDoc

If the documentation is not public hosted you can view it with GoDoc:

godoc --http :6060

You can see abbreviated documentation with go's built-in doc, for example:

go doc git.example.com/example/goserv/internal/api

http://localhost:6060

Test

Create a test database. It must have test in the name.

DROP DATABASE "goserv_test"; CREATE DATABASE "goserv_test";

Run the tests:

export TEST_DATABASE_URL='postgres://postgres:postgres@localhost:5432/goserv_test'
go test -mod=vendor ./...

Dependencies

This setup can be run on a VPS, such as Digital Ocean, OVH, or Scaleway for $5/month with minimal dependencies:

  • VPS
  • Caddy
  • PostgreSQL
  • Serviceman

Mac, Linux:

curl -fsS https://webinstall.dev | bash
export PATH="$HOME:/.local/bin:$PATH"
webi caddy serviceman postgres

VPS Setup

You should have a domain pointing to a VPS and create a user account named app (because that's a common convention). This script will create an app user, copying the authorized_keys from the root account.

my_vps='example.com'
ssh root@"$my_vps" 'curl -sS https://webinstall.dev/ssh-adduser | bash'

You can then login as a normal user.

ssh app@"$my_vps"

It is now safe to disable the root account.

Caddy (Automatic HTTPS Server)

curl -fsS https://webinstall.dev/caddy | bash

You can start Caddy as a system service under the app user like this:

sudo setcap 'cap_net_bind_service=+ep' "$(readlink $(command -v caddy))"

sudo env PATH="$PATH" \
    serviceman add --name caddy --username app \
    caddy run --config ./Caddyfile

See the Cheat Sheets at https://webinstall.dev/caddy and https://webinstall.dev/serviceman

PostgreSQL (Database)

curl -fsS https://webinstall.dev/postgres | bash

You can start Postgres as a system service under the app user like this:

sudo env PATH="$PATH" \
    serviceman add --name postgres --username app -- \
    postgres -D /home/app/.local/share/postgres/var -p 5432

Username and password are set to 'postgres' by default:

psql 'postgres://postgres:postgres@localhost:5432/postgres'

See the Cheat Sheets at https://webinstall.dev/postgres and https://webinstall.dev/serviceman

Licenses

Copyright 2020 The GoServ Authors. All rights reserved.

Exceptions

These are probably also in the Public Domain.
(gathering the official data from any source would yield the same dataset)