Skip to content

Latest commit

 

History

History
135 lines (100 loc) · 3.81 KB

File metadata and controls

135 lines (100 loc) · 3.81 KB

API Development Workflow

Step-by-step guide for creating APIs, implementing services, managing OpenAPI specs, and generating clients.

1. Creating a New API

# 1. Create new API from template
make api-new API=my-service-api

# 2. Define your types and trait in apis/my-service-api/src/lib.rs
# 3. Add to workspace Cargo.toml members list
# 4. Register in openapi-manager/src/main.rs
# 5. Generate OpenAPI spec
make openapi-generate

Example API trait definition:

#[dropshot::api_description]
pub trait MyServiceApi {
    type Context: Send + Sync + 'static;

    #[endpoint {
        method = GET,
        path = "/resource/{id}",
        tags = ["resources"],
    }]
    async fn get_resource(
        rqctx: RequestContext<Self::Context>,
        path: Path<ResourceId>,
    ) -> Result<HttpResponseOk<Resource>, HttpError>;
}

2. Implementing a Service

# 1. Create new service from template
make service-new SERVICE=my-service API=my-service-api

# 2. Implement the API trait in services/my-service/src/main.rs
# 3. Add to workspace Cargo.toml members list
# 4. Build and test
make service-build SERVICE=my-service
make service-test SERVICE=my-service

Example implementation:

enum MyServiceImpl {}

impl MyServiceApi for MyServiceImpl {
    type Context = ApiContext;

    async fn get_resource(
        rqctx: RequestContext<Self::Context>,
        path: Path<ResourceId>,
    ) -> Result<HttpResponseOk<Resource>, HttpError> {
        // Your implementation here
    }
}

// In main():
let api = my_service_api::my_service_api_mod::api_description::<MyServiceImpl>()?;

See services/bugview-service for a complete working example.

3. Managing OpenAPI Specs

Important: Generated OpenAPI specs are checked into git in openapi-specs/generated/. This enables:

  • Builds work without running openapi-manager first (jira-client depends on the checked-in spec)
  • API changes become visible in PRs through spec diffs
  • Version history tracks API evolution
# 1. Register your API in openapi-manager/src/main.rs

# 2. Generate specs (much faster than compiling implementations!):
make openapi-generate

# 3. Review the generated spec diffs:
git diff openapi-specs/generated/

# 4. Commit the updated specs:
git add openapi-specs/generated/
git commit -m "Update OpenAPI specs for my-api changes"

# List managed APIs
make openapi-list

# Check if specs are up-to-date (use in CI):
make openapi-check

The openapi-manager uses stub_api_description() which generates specs without needing to compile the full service implementation. The check command compares generated specs against what's committed in git to catch stale specs.

4. Generating Clients

Client code is generated by the client-generator tool and checked into git as src/generated.rs files. This makes generated types visible to grep, IDE navigation, and code review.

# 1. Create client from template
make client-new CLIENT=my-service-client API=my-service-api

# 2. Register the client in client-generator/src/main.rs
#    Add a ClientConfig entry with spec path, output path, and generation settings
# 3. Add to workspace Cargo.toml members list
# 4. Generate client code
make clients-generate

# 5. Build to verify
make client-build CLIENT=my-service-client
# Regenerate all client code after OpenAPI spec changes:
make clients-generate

# Check that generated code is up-to-date (use in CI):
make clients-check

Note: Generated src/generated.rs files are checked into git, just like OpenAPI specs. This means clients can be built without running client-generator first.