Service Scaffolding

Generating a complete Go web service from the nurago example project with make project

Besides the packages, the repository carries a working web service under examples/service and a generator that turns it into a new project with your own name, owner, and repository path. What you get is not a snippet to copy: it is a service with the lifecycle, configuration, routing, health endpoint, OpenAPI specifications, Docker build, packaging, and integration tests already wired and passing.

Generate a Project

git clone https://github.com/tecnickcom/nurago.git
cd nurago
cp project.cfg myproject.cfg

Edit myproject.cfg. The keys are the placeholders substituted throughout the generated tree:

NURAGOEXAMPLE=DUMMY
nuragoexample=dummy
nuragoexampleshortdesc=nurago Example project description
nuragoexamplelongdesc=nurago Example project long description
nuragoexampleauthor=author
nuragoexampleemail=test@example.com
nuragoexamplecvspath=github.com/test
nuragoexampleprojectlink=https://github.com/test/dummy
nuragoexampleowner=test
nuragoexamplevcsgit=https://github.com/test/dummy.git

nuragoexample is the lowercase project name (used for the binary, the package paths, the config directory, and file names), and NURAGOEXAMPLE its uppercase form (used for environment variable prefixes). nuragoexamplecvspath is the repository host and owner path the module will live under.

Then generate:

make project CONFIG=myproject.cfg

The result is written under target/<cvspath>/<name>, with every file and directory renamed and every placeholder substituted, and with the local replace directive stripped from go.mod so the generated module depends on the published nurago release. Move it where it belongs:

mv target/github.com/test/dummy ~/GO/src/myproject/

First Run

From the new project directory:

make x

That runs the full sequence from scratch: format, clean, download and get dependencies, generate documentation and mocks, run the QA pipeline (linters, configuration file checks, unit tests, coverage), and build the binary. make help lists every target.

To go all the way to a container and exercise it:

make docker      # build a scratch container for the service
make dockertest  # run it in an ephemeral Docker Compose environment

make dockertest runs the OpenAPI specification against randomly generated Schemathesis tests and then the venom API test suite, so a generated project has end-to-end coverage on the first commit. The Schemathesis check selection, including per-operation overrides, lives in schemathesis.toml: a --checks flag on the command line would replace that file rather than add to it.

What the Generated Service Contains

  • A three-server runtime layout: separate monitoring, private, and public HTTP servers, so operational traffic is isolated from internal and external APIs from the start.
  • Configuration-first bootstrap in internal/cli: startup, configuration loading and validation, logging, metrics, health checks, and graceful shutdown are wired in one place (cli.go, config.go, bind.go).
  • Operational assets under resources: local Docker Compose environments, integration test fixtures, RPM and DEB packaging, init scripts, Grafana dashboards, and database schemas for MySQL and PostgreSQL.
  • OpenAPI specifications for the public, private, and monitoring surfaces.
  • One worked feature, the item store: a domain package, a database-backed repository, public endpoints, unit tests, and integration tests, so the layout is shown in use rather than left empty.
  • Generated documentation and build output kept out of the source packages, in doc and target.

The files worth reading first, in order, are cmd/main.go, internal/cli/cli.go, and internal/cli/bind.go: they show the same lifecycle described in /docs/getting-started/, applied to a real service. After those, internal/item and internal/httphandlerpub show where application code goes.

The Item Feature

The item feature is the example of application code in the generated tree: a named thing with a quantity, stored in a relational database. It is split across three layers, each knowing only the one below.

FileContents
internal/item/item.goDomain types, the limits applied to accepted values, and the sentinel errors ErrNotFound, ErrConflict, and ErrValidation, wrapped at each layer and matched with errors.Is by the handlers.
internal/item/service.goThe business rules, depending on a Store interface declared alongside them, so the service tests run against a hand-written fake and never reach a database. Identifiers are UUIDv7 values from /packages/random/.
internal/item/repository.goThe SQL implementation of Store, and the only place a column is named. Reads use the read connection, writes the main one. It targets MySQL: the placeholders and the duplicate-key mapping are driver-specific.
internal/httphandlerpub/item.goThe HTTP layer: request decoding, query parsing, and the mapping from sentinel errors to status codes.

The public routes are POST /items, GET /items, GET /items/{id}, and DELETE /items/{id}. ErrNotFound answers 404, ErrConflict 409, and ErrValidation 422; anything else is logged and answered with a 500 whose body says nothing. Validation happens in the HTTP and service layers rather than at the database, so a quantity outside the column range or a name longer than the column width is a 422 and not a failed insert.

The feature is gated on the database. internal/cli/bind.go builds the item service from the connections returned by newDatabases only when the database is enabled; otherwise the public handler is constructed with a nil service and the item routes are never registered, leaving the rest of the service to start as before. The endpoints are documented in openapi_public.yaml and covered by the venom suite under resources/test/venom.

When to Use It

Use the generator when starting a new service and you want the operational surface settled before the first endpoint exists. Use the individual packages instead when adding capability to a service that already exists: nothing in the packages requires this layout.


Previous: /docs/getting-started/

Overview: /docs/

Next: /docs/dependency-footprint/

The long form

This page is a reference. For the same ground covered as a narrative, with one service built end to end, Building a Production REST API in Go is a twenty-part guide on tecnick.com.