Skip to content

Latest commit

 

History

History
126 lines (89 loc) · 3.57 KB

File metadata and controls

126 lines (89 loc) · 3.57 KB

API Development Guidelines

Spec-First Workflow

All API changes start with the OpenAPI specification. Never implement an endpoint without first defining it in the spec.

Steps for API Changes

  1. Edit spec/openapi.yaml — define endpoints, parameters, schemas
  2. Run make generate — regenerate pkg/generated/api.go
  3. Run make openapi-json — update JSON version
  4. Implement in pkg/routes/server_adapter.go — the ServerAdapter must satisfy generated.ServerInterface
  5. Add service logic in pkg/services/ if needed
  6. Add tests
  7. Run make validate-api to verify spec compliance

Generated Code

pkg/generated/api.go is auto-generated by oapi-codegen. Configuration is in oapi-codegen.yaml:

package: generated
generate:
  models: true
  chi-server: true
  client: false
  embedded-spec: true
output: pkg/generated/api.go

Never edit pkg/generated/api.go. All behavioral logic goes in server_adapter.go.

Server Adapter Pattern

The ServerAdapter struct implements generated.ServerInterface. It delegates to service-layer objects:

type ServerAdapter struct {
    quickstartService *services.QuickstartService
    helpTopicService  *services.HelpTopicService
    favoriteService   *services.FavoriteService
    progressService   *services.ProgressService
}

Each handler method should:

  1. Parse and validate parameters (including legacy format support)
  2. Call the appropriate service method
  3. Format the response using generated types
  4. Set appropriate HTTP status codes

Parameter Handling

Legacy Format Support

The API supports both OpenAPI-standard and legacy bracket-notation parameters:

Standard Legacy Both must work
bundle=rhel&bundle=insights bundle[]=rhel&bundle[]=insights Yes
product-families=ansible product-families[]=ansible Yes

When adding new array parameters, always implement both formats. Use r.URL.Query() to check for legacy [] suffixed keys.

Pagination

  • limit (default: 50) — number of results
  • offset (default: 0) — skip count
  • limit=-1 — returns all results (no pagination)
  • limit=0 or limit<-1 — defaults to 50

Adding New Parameters

  1. Define in spec/openapi.yaml under components/parameters
  2. Reference in the endpoint's parameters list
  3. Regenerate: make generate
  4. Parse in server adapter, including legacy format fallback
  5. Pass to the service layer

Response Conventions

Success

{"data": [...]}

Always wrap results in a data key, even for single items.

Errors

Use generated error types:

// 400 Bad Request
msg := "Invalid parameter"
resp := generated.BadRequest{Msg: &msg}

// 404 Not Found
msg := "Quickstart not found"
resp := generated.NotFound{Msg: &msg}

Set Content-Type: application/json and the appropriate status code before encoding.

Status Codes

Code When
200 Successful read/update
400 Validation error, invalid parameters
404 Resource not found

Filtering

The service layer supports tag-based filtering. Tag types: bundle, application, product-families, use-case, content, kind, topic.

Filter priority in the service layer:

  1. Exact name match (highest)
  2. Tag filtering + display name
  3. Display name only
  4. No filters (return all, paginated)

Backward Compatibility

Prefer additive changes. Removing or renaming parameters, changing response shapes, or altering filter behavior can break the HCC frontend (learning-resources repo). When in doubt, support both old and new formats.