📖 3 min read (~ 500 words).

Task tracker

The task-tracker example is a larger, realistic CRUD API — an issue tracker with tasks, comments and file attachments. Its spec is the one go-swagger uses to exercise code generation, so it deliberately packs in almost every construct: nested resources, composition, arrays, file uploads, and multiple security schemes. It’s the best example to see what the generator produces for a non-trivial contract.

Tip

Source: task-tracker/. Generated with swagger generate server --name TaskTracker --spec ./swagger.yml --principal any.

The API surface

The spec defines a full CRUD surface across three nested resources:

PathOperations
/taskslistTasks, createTask
/tasks/{id}getTaskDetails, updateTask, deleteTask
/tasks/{id}/commentsaddCommentToTask, getTaskComments
/tasks/{id}/filesuploadTaskFile

Each becomes a typed handler on the generated API, with parameters (path, query, body, multipart) bound and validated for you.

Model composition

The spec builds Task on top of a shared TaskCard, and the generator preserves that with Go embedding — plus read-only fields, maps of attachments, and slices of related models:

type Task struct {
	TaskCard

	// The attached files.
	//
	// An issue can have at most 20 files attached to it.
	//
	Attachments map[string]TaskAttachmentsAnon `json:"attachments,omitempty"`

	// The 5 most recent items for this issue.
	//
	// The detail view of an issue includes the 5 most recent comments.
	// This field is read only, comments are added through a separate process.
	//
	// Read Only: true
	Comments []*Comment `json:"comments"`

	// The time at which this issue was last updated.
	//
	// This field is read only so it's only sent as part of the response.
	//
	// Read Only: true
	// Format: date-time
	LastUpdated strfmt.DateTime `json:"lastUpdated,omitempty"`

	// last updated by
	LastUpdatedBy *UserCard `json:"lastUpdatedBy,omitempty"`

	// reported by
	ReportedBy *UserCard `json:"reportedBy,omitempty"`
}

Full source: task-tracker/models/task.go

Read-only fields (Comments, LastUpdated) are populated by the server on responses and ignored on input, exactly as the spec declares.

Two API-key schemes

The spec declares two apiKey security definitions — one carried as a query parameter, one as a header:

api_key:
  type: apiKey
  name: token
  in: query
token_header:
  type: apiKey
  name: X-Token
  in: header

Full source: task-tracker/swagger.yml

The generator turns each into an authenticator hook you implement. The scaffold leaves them returning NotImplemented; you fill in the token validation:

// Applies when the "token" query is set
if api.APIKeyAuth == nil {
	api.APIKeyAuth = func(token string) (any, error) {
		_ = token

		return nil, errors.NotImplemented("api key auth (api_key) token from query param [token] has not yet been implemented")
	}
}
// Applies when the "X-Token" header is set
if api.TokenHeaderAuth == nil {
	api.TokenHeaderAuth = func(token string) (any, error) {
		_ = token

		return nil, errors.NotImplemented("api key auth (token_header) X-Token from header param [X-Token] has not yet been implemented")
	}
}

Full source: task-tracker/restapi/configure_task_tracker.go

For worked authentication examples (basic, api-key, composed, OAuth2), see the Authentication guides.

  • Todo list server — the minimal CRUD server to start from.
  • File server — the type: file upload mechanics used by /tasks/{id}/files.
  • Petstore — another full spec, generated end to end.