Skip to content

Commit 401eaf5

Browse files
Initial commit
0 parents  commit 401eaf5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+6827
-0
lines changed

.github/workflows/lint.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: lint
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
env:
9+
GOPRIVATE: "github.com/speakeasy-api"
10+
jobs:
11+
golangci:
12+
name: lint
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/setup-go@v3
16+
with:
17+
go-version: 1.18
18+
19+
- uses: actions/checkout@v3
20+
- name: golangci-lint
21+
uses: golangci/golangci-lint-action@v3
22+
with:
23+
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
24+
version: latest

.github/workflows/tests.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
env:
9+
GOPRIVATE: "github.com/speakeasy-api"
10+
jobs:
11+
tests:
12+
runs-on: ubuntu-latest
13+
14+
strategy:
15+
fail-fast: true
16+
matrix:
17+
go-version: [1.18.x]
18+
19+
name: Tests - Go ${{ matrix.go-version }}
20+
21+
steps:
22+
- name: Checkout the code
23+
uses: actions/checkout@v2
24+
25+
- name: Install Go
26+
uses: actions/setup-go@v2
27+
with:
28+
go-version: ${{ matrix.go-version }}
29+
30+
- name: Run the tests
31+
run: go test ./...

.gitignore

Whitespace-only changes.

.golangci.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
linters:
2+
enable-all: true
3+
disable:
4+
- lll
5+
- varnamelen
6+
- exhaustivestruct
7+
- exhaustruct
8+
- godox
9+
- nlreturn
10+
- wsl
11+
- wrapcheck
12+
- gochecknoglobals
13+
- paralleltest
14+
- dupl
15+
- containedctx
16+
# Deprecated
17+
- golint
18+
- maligned
19+
- interfacer
20+
- scopelint
21+
issues:
22+
exclude:
23+
- "returns unexported type"
24+
- "unlambda"
25+
- "should rewrite http.NewRequestWithContext"
26+
exclude-rules:
27+
# Exclude some linters from running on tests files.
28+
- path: _test\.go
29+
linters:
30+
- scopelint
31+
- goerr113
32+
- funlen
33+
- gocognit
34+
- cyclop
35+
- path: _exports_test\.go
36+
linters:
37+
- testpackage
38+
include:
39+
- EXC0012
40+
- EXC0013
41+
- EXC0014
42+
- EXC0015
43+
run:
44+
go: "1.14"

Dockerfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# syntax=docker/dockerfile:1
2+
3+
# Build the application
4+
5+
FROM golang:1.18-alpine AS build
6+
7+
WORKDIR /app
8+
9+
COPY ./ ./
10+
11+
RUN go mod download
12+
13+
RUN ls -lrt
14+
15+
RUN go build -o ./server ./cmd/server/main.go
16+
17+
# Build the server image
18+
19+
FROM alpine:latest
20+
21+
RUN apk --no-cache add ca-certificates
22+
23+
WORKDIR /root/
24+
25+
COPY --from=0 /app/server ./
26+
COPY --from=0 /app/config/config-docker.yaml ./config/config.yaml
27+
COPY --from=0 /app/migrations/ ./migrations/
28+
29+
CMD ["./server"]

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# speakeasy-example-rest-service-go
2+
3+
## Getting Started
4+
5+
### Prerequisites
6+
7+
* Go 1.18 (though should be backwards compatible with earlier versions)
8+
9+
### Running locally
10+
11+
1. From root of the repo
12+
2. Run `go mod download` to install dependencies
13+
3. Run `docker-compose up -d postgres` to run the postgres dependency
14+
4. Run `go run cmd/server/main.go` will start the server on port 8080
15+
16+
### Running via docker
17+
18+
1. From root of the repo
19+
2. Run `docker-compose up` will start the dependencies and server on port 8080
20+
21+
### Postman
22+
23+
I have provided Postman collections for testing out the REST endpoints exposed by the service.
24+
There is a `Bootstrap Users` collection that can be run using the `Run collection` tool in Postman that will create 100 users to test the search endpoint with.
25+
26+
The collections will need an environment setup with `scheme`, `port` and `host` variables setup with values of `http`, `8080` and `localhost` respectively.
27+
28+
### Run tests
29+
30+
The service contains a collection of unit and integration tests for testing the various layers of the service. Some of the integration tests use docker to spin up dependencies on demand (ie a postgres db) so just be aware that docker is needed to run the tests.
31+
32+
1. From root of the repo
33+
2. Run `go test ./...`

cmd/server/main.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package main
2+
3+
import (
4+
"context"
5+
6+
"github.com/cenkalti/backoff/v4"
7+
"github.com/speakeasy-api/speakeasy-example-rest-service-go/internal/config"
8+
"github.com/speakeasy-api/speakeasy-example-rest-service-go/internal/core/app"
9+
"github.com/speakeasy-api/speakeasy-example-rest-service-go/internal/core/drivers/psql"
10+
"github.com/speakeasy-api/speakeasy-example-rest-service-go/internal/core/listeners/http"
11+
"github.com/speakeasy-api/speakeasy-example-rest-service-go/internal/core/logging"
12+
"github.com/speakeasy-api/speakeasy-example-rest-service-go/internal/events"
13+
httptransport "github.com/speakeasy-api/speakeasy-example-rest-service-go/internal/transport/http"
14+
"github.com/speakeasy-api/speakeasy-example-rest-service-go/internal/users"
15+
"github.com/speakeasy-api/speakeasy-example-rest-service-go/internal/users/store"
16+
17+
"go.uber.org/zap"
18+
)
19+
20+
func main() {
21+
app.Start(appStart)
22+
}
23+
24+
func appStart(ctx context.Context, a *app.App) ([]app.Listener, error) {
25+
// Load configuration from config/config.yaml which contains details such as DB connection params
26+
cfg, err := config.Load()
27+
if err != nil {
28+
return nil, err
29+
}
30+
31+
// Connect to the postgres DB
32+
db, err := initDatabase(ctx, cfg, a)
33+
if err != nil {
34+
return nil, err
35+
}
36+
37+
// Run our migrations which will update the DB or create it if it doesn't exist
38+
if err := db.MigratePostgres(ctx, "file://migrations"); err != nil {
39+
return nil, err
40+
}
41+
a.OnShutdown(func() {
42+
// Temp for development so database is cleared on shutdown
43+
if err := db.RevertMigrations(ctx, "file://migrations"); err != nil {
44+
logging.From(ctx).Error("failed to revert migrations", zap.Error(err))
45+
}
46+
})
47+
48+
// Instantiate and connect all our classes
49+
us := store.New(db.GetDB())
50+
e := events.New()
51+
u := users.New(us, e)
52+
53+
httpServer := httptransport.New(u, db.GetDB())
54+
55+
// Create a HTTP server
56+
h, err := http.New(httpServer, cfg.HTTP)
57+
if err != nil {
58+
return nil, err
59+
}
60+
61+
// Start listening for HTTP requests
62+
return []app.Listener{
63+
h,
64+
}, nil
65+
}
66+
67+
func initDatabase(ctx context.Context, cfg *config.Config, a *app.App) (*psql.Driver, error) {
68+
db := psql.New(cfg.PSQL)
69+
70+
err := backoff.Retry(func() error {
71+
return db.Connect(ctx)
72+
}, backoff.NewExponentialBackOff())
73+
if err != nil {
74+
return nil, err
75+
}
76+
77+
a.OnShutdown(func() {
78+
// Shutdown connection when server terminated
79+
logging.From(ctx).Info("shutting down db connection")
80+
if err := db.Close(ctx); err != nil {
81+
logging.From(ctx).Error("failed to close db connection", zap.Error(err))
82+
}
83+
})
84+
85+
return db, nil
86+
}

config/config-docker.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
http:
2+
port: "8080"
3+
psql:
4+
username: guest
5+
password: guest
6+
host: postgres
7+
port: 5432
8+
database: speakeasy

config/config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
http:
2+
port: "8080"
3+
psql:
4+
username: guest
5+
password: guest
6+
host: localhost
7+
port: 5432
8+
database: speakeasy

docker-compose.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version: "3.9"
2+
services:
3+
app:
4+
build: .
5+
ports:
6+
- "8080:8080"
7+
depends_on:
8+
- postgres
9+
postgres:
10+
image: postgres:alpine
11+
restart: always
12+
environment:
13+
POSTGRES_USER: guest
14+
POSTGRES_PASSWORD: guest
15+
POSTGRES_DB: speakeasy
16+
ports:
17+
- "5432:5432"

0 commit comments

Comments
 (0)