Skip to content

RedHatInsights/quickstarts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Quickstarts

Backend service for integrated quickstarts.

Run the service locally

  1. There are environment variables required for the application to start. It's recommended you copy .env.example to .env and set these appropriately for local development.
  2. Start required infrastructure (database): make infra
  3. Migrate the database: make migrate. It will seed the DB with testing quickstart
  4. Start the development server: make dev (generates API and starts server)

Alternative: Manual steps

  • Generate API: make generate
  • Start server: go run .
  1. Query data:
curl --location --request GET 'http://localhost:8000/api/quickstarts/v1/quickstarts/'

curl --location --request GET 'http://localhost:8000/api/quickstarts/v1/quickstarts/?bundle[]=rhel&bundle[]=insights'

IMPORTANT

oc port-forward -n quickstarts svc/quickstarts-service 8000:8000!

Sample requests

Create progress

curl --location --request POST 'http://localhost:8000/api/quickstarts/v1/progress' --header 'Content-Type: application/json' --data-raw '{
"accountId": 123, "quickstartName": "some-name", "progress": {"Some": "Progress-updated"}
}'

Delete progress

curl --location --request DELETE 'http://localhost:8000/api/quickstarts/v1/progress/14'

API Developer Guide

This section explains the API architecture and how to contribute to the backend service.

Architecture Overview

The API follows a layered architecture using OpenAPI code generation:

OpenAPI Spec → oapi-codegen → Server Adapter → Services → Database
     ↓              ↓             ↓            ↓         ↓
spec/openapi.yaml → pkg/generated → pkg/routes → pkg/services → pkg/database

Key Principles

  1. OpenAPI Spec is Source of Truth: The specification in spec/openapi.yaml defines the API contract
  2. Implementation Follows Spec: Server adapter and services implement the behavior defined in the OpenAPI spec
  3. Spec-First Development: API changes start with updating the OpenAPI specification, then implementing
  4. Backward Compatibility: Legacy parameter formats must be supported to avoid frontend regressions

Core Components

1. OpenAPI Specification (spec/openapi.yaml)

Defines the API contract with endpoints, schemas, parameters, and validation rules.

Regenerate after changes:

make generate
make openapi-json

2. Generated Code (pkg/generated/api.go)

Auto-generated by oapi-codegen from the OpenAPI spec. ⚠️ Never edit this file directly.

3. Server Adapter (pkg/routes/server_adapter.go)

Implements the generated ServerInterface and contains:

  • Parameter parsing and validation
  • Legacy format support
  • Service layer orchestration
  • Response formatting

4. Service Layer (pkg/services/)

Contains business logic and data access.

5. Database Layer (pkg/database/)

Handles database connections and models via GORM.

Parameter Handling

Standard vs Legacy Formats

The API supports both OpenAPI-standard and legacy array parameter formats:

Parameter Type Standard Format Legacy Format Example
Single Array bundle=rhel&bundle=insights bundle[]=rhel&bundle[]=insights Multiple values
Product Families product-families=ansible product-families[]=ansible ansible, tower
Name/Display Name name=quickstart-name display-name[]=name Single strings

Adding New Parameters

  1. Add to OpenAPI spec (spec/openapi.yaml):
parameters:
  NewParam:
    name: new-param
    description: Description of new parameter
    in: query
    required: false
    schema:
      type: array
      items:
        type: string
    explode: true
    style: form
  1. Reference in endpoint:
parameters:
- $ref: '#/components/parameters/NewParam'
  1. Regenerate code: make generate

  2. Update server adapter to handle the parameter

  3. Update service layer to use the new parameter

Pagination

Standard Pagination

  • limit: Number of results to return (default: 50)
  • offset: Number of results to skip (default: 0)

Special Limit Values

  • limit=-1: No pagination - returns ALL results
  • limit=0: Invalid, defaults to 50
  • limit<-1: Invalid, defaults to 50

Filtering System

Tag-Based Filtering

The API supports filtering by multiple tag types:

  • bundle: Filter by bundle tags (rhel, insights, etc.)
  • application: Filter by application tags
  • product-families: Filter by product family tags
  • use-case: Filter by use case tags
  • content: Filter by content type tags
  • kind: Filter by kind tags
  • topic: Filter by topic tags

Name/Display Name Filtering

  • name: Exact match on quickstart name
  • display-name: Partial match (ILIKE) on display name in content JSON

Filter Priority

The service layer applies filters in this order:

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

Adding New Endpoints

Follow this spec-first workflow:

  1. Define in OpenAPI Spec (spec/openapi.yaml) - Design the API contract first
  2. Regenerate Code: make generate - Generate types and interfaces
  3. Implement in Server Adapter (pkg/routes/server_adapter.go) - Implement the generated interface
  4. Add Service Layer Logic (pkg/services/) - Add business logic and data access
  5. Add Tests - Test the complete endpoint functionality

Important: Always start with the OpenAPI specification. The spec defines the contract that the implementation must follow.

Response Format Standards

Success Response

{
  "data": [/* array of results */]
}

Error Response

{
  "msg": "Error message description"
}

HTTP Status Codes

  • 200: Success
  • 400: Bad Request (validation errors, invalid parameters)
  • 404: Not Found (resource doesn't exist)

Testing

Running Tests

# All tests
go test ./...

# Specific package
go test ./pkg/routes -v

# Specific test
go test ./pkg/routes -run TestGetQuickstarts -v

Building and Deployment

Local Development

# Setup
cp .env.example .env  # Configure environment variables

# Install dependencies
go mod download

# Start infrastructure (database)
make infra

# Migrate database (includes test data seeding)
make migrate

# Quick start: Generate API and start development server
make dev

# Or run individual steps:
# Generate API code
make generate

# Start server manually
go run .

# Run tests
make test

# Build binary
go build -o quickstarts

# Cleanup: Stop infrastructure
make stop-infra

Docker Build

# Build with all generation steps
docker build -t quickstarts .

The Docker build includes API code generation, OpenAPI JSON conversion, validation, testing, and binary compilation.

Common Development Patterns

Parameter Validation

if requiredParam == "" {
    w.WriteHeader(http.StatusBadRequest)
    w.Header().Set("Content-Type", "application/json")
    msg := "Required parameter missing"
    resp := generated.BadRequest{Msg: &msg}
    json.NewEncoder(w).Encode(resp)
    return
}

Error Handling

if err != nil {
    w.WriteHeader(http.StatusBadRequest)
    w.Header().Set("Content-Type", "application/json")
    msg := err.Error()
    resp := generated.BadRequest{Msg: &msg}
    json.NewEncoder(w).Encode(resp)
    return
}

Response Formatting

// Convert internal models to API types
genResults := make([]generated.SomeType, len(results))
for i, result := range results {
    genResults[i] = result.ToAPI()
}

// Standard response format
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
resp := map[string][]generated.SomeType{"data": genResults}
json.NewEncoder(w).Encode(resp)

Best Practices

  1. Always maintain backward compatibility
  2. Test both standard and legacy parameter formats
  3. Document parameter behavior changes
  4. Use consistent error response formats
  5. Add tests for new functionality
  6. Update OpenAPI spec to match implementation
  7. Validate edge cases (empty arrays, special values like -1)

Troubleshooting

Common Issues

  1. Parameter not working: Check both OpenAPI spec and legacy parameter parsing
  2. Generated code outdated: Run make generate after spec changes
  3. Type mismatches: Ensure OpenAPI types match Go service layer expectations
  4. Tests failing: Check for breaking changes in parameter handling

For questions about the API architecture, refer to spec/openapi.yaml as the authoritative source of API behavior, with implementation details in pkg/routes/server_adapter.go.

About

Backend service for integrated quickstarts.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 63