Boilerplate for how I like to write a backend web service.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
AJ ONeal 80977071ff update go-gitver 4 месяцев назад
assets add more CLI options and API scaffolding 4 месяцев назад
examples add more CLI options and API scaffolding 4 месяцев назад
internal add more CLI options and API scaffolding 4 месяцев назад
public add more CLI options and API scaffolding 4 месяцев назад
tools add more CLI options and API scaffolding 4 месяцев назад
vendor update go-gitver 4 месяцев назад
.gitignore add more CLI options and API scaffolding 4 месяцев назад
.goreleaser.yml add more CLI options and API scaffolding 4 месяцев назад
.ignore add more CLI options and API scaffolding 4 месяцев назад
.prettierignore initial commit 5 месяцев назад
.prettierrc initial commit 5 месяцев назад
AUTHORS update LICENSE and AUTHORS 5 месяцев назад
LICENSE initial commit 5 месяцев назад
README.md add /api/version 4 месяцев назад
doc.go add more CLI options and API scaffolding 4 месяцев назад
go.mod update go-gitver 4 месяцев назад
go.sum update go-gitver 4 месяцев назад
main.go remove extraneous version newline 4 месяцев назад

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)