Claude-skill-registry contract-first-design
Design and manage API contracts before implementation using OpenAPI and AsyncAPI specifications for contract-first development
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/contract-first-design" ~/.claude/skills/majiayu000-claude-skill-registry-contract-first-design && rm -rf "$T"
manifest:
skills/data/contract-first-design/SKILL.mdsource content
Contract-First Design Skill
When to Use This Skill
Use this skill when:
- Contract First Design tasks - Working on design and manage api contracts before implementation using openapi and asyncapi specifications for contract-first development
- Planning or design - Need guidance on Contract First Design approaches
- Best practices - Want to follow established patterns and standards
Overview
Apply contract-first development methodology for APIs, ensuring specifications drive implementation.
Contract-First Methodology
Core Principles
contract_first_principles: design_before_code: description: "API specification comes before implementation" benefits: - "Early feedback from consumers" - "Parallel development enabled" - "Clear contract for testing" - "Documentation from day one" specification_as_source_of_truth: description: "Spec is authoritative, code conforms to it" enforcement: - "Generate code from spec" - "Validate implementation against spec" - "CI/CD gates on spec compliance" consumer_centric: description: "Design for consumer needs, not provider convenience" practices: - "Involve consumers in design reviews" - "Consumer-driven contract testing" - "Gather real-world usage patterns" evolution_over_revolution: description: "Evolve contracts without breaking consumers" practices: - "Semantic versioning" - "Backward compatibility by default" - "Deprecation before removal"
Development Workflow
contract_first_workflow: phases: 1_design: activities: - "Identify API consumers and use cases" - "Define resources and operations" - "Draft specification (OpenAPI/AsyncAPI)" - "Review with stakeholders" artifacts: - "Draft API specification" - "Use case documentation" gate: "Specification approved by consumers" 2_validate: activities: - "Lint specification for style/standards" - "Check backward compatibility" - "Generate mock server" - "Consumer acceptance testing with mocks" artifacts: - "Lint report" - "Compatibility report" - "Mock server configuration" gate: "Consumers validated against mocks" 3_implement: activities: - "Generate server stubs" - "Implement business logic" - "Contract testing against spec" - "Integration testing" artifacts: - "Generated code" - "Contract test results" gate: "Implementation passes contract tests" 4_publish: activities: - "Publish specification to catalog" - "Generate documentation" - "Update changelog" - "Notify consumers" artifacts: - "Published specification" - "API documentation portal" - "Changelog entry" gate: "Documentation live, consumers notified" 5_operate: activities: - "Monitor API usage" - "Collect consumer feedback" - "Track breaking change requests" - "Plan next version" artifacts: - "Usage metrics" - "Feedback log" - "Deprecation schedule"
Contract Management
Specification Organization
specification_organization: directory_structure: recommended: specs/ openapi/ order-service.yaml customer-service.yaml inventory-service.yaml asyncapi/ order-events.yaml inventory-events.yaml shared/ schemas/ common-types.yaml error-responses.yaml parameters/ pagination.yaml security/ auth-schemes.yaml file_naming: pattern: "{service-name}.yaml" versioned: "{service-name}-v{major}.yaml" modular_specs: description: "Split large specs into components" approach: main_file: "Defines paths, references components" components_dir: "Reusable schemas, parameters, responses" shared_dir: "Cross-API shared definitions" example_main: openapi: "3.1.0" info: title: "Order Service API" version: "1.0.0" paths: $ref: "./paths/orders.yaml" components: schemas: $ref: "./schemas/_index.yaml"
Version Management
version_management: semantic_versioning: major: "Breaking changes" minor: "Backward-compatible additions" patch: "Backward-compatible fixes" version_in_spec: location: "info.version" format: "MAJOR.MINOR.PATCH" api_versioning_strategies: url_path: spec_example: servers: - url: "https://api.example.com/v1" change_approach: "New spec file for major versions" header: spec_example: parameters: API-Version: in: header required: false schema: type: string default: "2025-01-01" changelog_requirements: location: "CHANGELOG.md alongside spec" format: "Keep a Changelog" content: - "Version number and date" - "Added: new endpoints/fields" - "Changed: modified behavior" - "Deprecated: marked for removal" - "Removed: breaking deletions" - "Fixed: bug fixes" - "Security: vulnerability patches"
Breaking Change Detection
breaking_changes: definition: "Changes that can break existing consumers" openapi_breaking: removals: - "Remove endpoint" - "Remove required response field" - "Remove enum value" - "Remove supported content type" modifications: - "Change field type" - "Add required request field" - "Narrow validation (smaller max, larger min)" - "Change authentication requirements" renames: - "Rename field (equivalent to remove + add)" - "Change endpoint path" asyncapi_breaking: removals: - "Remove channel" - "Remove message type" - "Remove required payload field" modifications: - "Change payload schema incompatibly" - "Change channel address format" - "Modify required headers" detection_tools: openapi: - "openapi-diff" - "oasdiff" - "speccy" asyncapi: - "asyncapi/diff" ci_integration: script: | # Compare current spec against main branch oasdiff breaking main.yaml current.yaml if [ $? -ne 0 ]; then echo "Breaking changes detected!" exit 1 fi
C# Models for Contract Management
namespace SpecDrivenDevelopment.ContractFirst; /// <summary> /// Represents an API contract lifecycle state /// </summary> public enum ContractStatus { Draft, InReview, Approved, Implementing, Published, Deprecated, Retired } /// <summary> /// API contract metadata /// </summary> public record ApiContract { public required string Id { get; init; } public required string Name { get; init; } public required string Version { get; init; } public required ContractType Type { get; init; } public required ContractStatus Status { get; init; } public required string SpecificationPath { get; init; } public string? Description { get; init; } public List<string> Owners { get; init; } = []; public List<string> Consumers { get; init; } = []; public DateTimeOffset CreatedAt { get; init; } public DateTimeOffset? PublishedAt { get; init; } public DateTimeOffset? DeprecatedAt { get; init; } public DateTimeOffset? SunsetAt { get; init; } } public enum ContractType { OpenApi, AsyncApi, GraphQL, gRPC } /// <summary> /// Tracks changes between contract versions /// </summary> public record ContractChange { public required string ContractId { get; init; } public required string FromVersion { get; init; } public required string ToVersion { get; init; } public required ChangeType Type { get; init; } public required BreakingLevel Breaking { get; init; } public required string Path { get; init; } public required string Description { get; init; } public string? MigrationGuide { get; init; } } public enum ChangeType { Added, Modified, Deprecated, Removed } public enum BreakingLevel { None, Minor, // Backward compatible Major // Breaking change } /// <summary> /// Contract validation result /// </summary> public record ContractValidationResult { public required bool IsValid { get; init; } public List<ValidationIssue> Issues { get; init; } = []; public List<ContractChange> Changes { get; init; } = []; public bool HasBreakingChanges => Changes.Any(c => c.Breaking == BreakingLevel.Major); } public record ValidationIssue { public required ValidationSeverity Severity { get; init; } public required string Code { get; init; } public required string Message { get; init; } public required string Path { get; init; } public string? Suggestion { get; init; } } public enum ValidationSeverity { Error, Warning, Info } /// <summary> /// Consumer contract registration /// </summary> public record ConsumerContract { public required string ConsumerId { get; init; } public required string ConsumerName { get; init; } public required string ProviderId { get; init; } public required string ProviderVersion { get; init; } public List<string> UsedEndpoints { get; init; } = []; public List<string> UsedSchemas { get; init; } = []; public DateTimeOffset RegisteredAt { get; init; } public DateTimeOffset? LastVerifiedAt { get; init; } } /// <summary> /// Service for contract management /// </summary> public interface IContractService { Task<ApiContract> CreateContractAsync(CreateContractRequest request); Task<ApiContract> GetContractAsync(string id); Task<IReadOnlyList<ApiContract>> ListContractsAsync(ContractFilter? filter = null); Task<ContractValidationResult> ValidateContractAsync(string id); Task<ContractValidationResult> CompareVersionsAsync(string id, string fromVersion, string toVersion); Task PublishContractAsync(string id); Task DeprecateContractAsync(string id, DateTimeOffset sunsetDate); Task RegisterConsumerAsync(string contractId, ConsumerContract consumer); Task<IReadOnlyList<ConsumerContract>> GetConsumersAsync(string contractId); } public record CreateContractRequest { public required string Name { get; init; } public required ContractType Type { get; init; } public required string SpecificationContent { get; init; } public string? Description { get; init; } public List<string> Owners { get; init; } = []; } public record ContractFilter { public ContractType? Type { get; init; } public ContractStatus? Status { get; init; } public string? Owner { get; init; } public string? Consumer { get; init; } }
Contract Testing
Provider Verification
provider_verification: description: "Verify implementation matches specification" approaches: schema_validation: description: "Validate request/response against spec" tools: - "express-openapi-validator" - "NSwag middleware" - "Spectral" contract_tests: description: "Test endpoints match spec exactly" tools: - "Dredd" - "Schemathesis" - "Prism" dotnet_example: integration_test: | [Fact] public async Task GetOrder_ReturnsValidResponse() { // Arrange var spec = await OpenApiDocument.FromFileAsync("specs/order-service.yaml"); var validator = new OpenApiValidator(spec); // Act var response = await _client.GetAsync("/orders/123"); var body = await response.Content.ReadAsStringAsync(); // Assert var result = validator.ValidateResponse( "/orders/{orderId}", "get", (int)response.StatusCode, body); Assert.True(result.IsValid, result.ErrorMessage); } ci_pipeline: steps: - "Load OpenAPI/AsyncAPI spec" - "Start application under test" - "Run contract tests against all endpoints" - "Fail build if any contract violation"
Consumer-Driven Contracts
consumer_driven_contracts: description: "Consumers define expected provider behavior" workflow: 1_consumer_defines: action: "Consumer creates contract with expected interactions" artifact: "Pact file or similar contract" 2_provider_verifies: action: "Provider runs consumer contracts" validation: "Provider can satisfy all consumer expectations" 3_publish: action: "Publish verified contracts to broker" enables: "Can-I-Deploy checks" pact_example: consumer_test: | [Fact] public async Task GetOrder_ExpectedBehavior() { var pact = Pact.V3("OrderConsumer", "OrderProvider"); pact.Given("Order 123 exists") .UponReceiving("A request for order 123") .WithRequest(HttpMethod.Get, "/orders/123") .WillRespond() .WithStatus(200) .WithJsonBody(new { id = "123", status = Match.Type("pending"), totalAmount = Match.Decimal(99.99m) }); await pact.VerifyAsync(async ctx => { var client = new OrderClient(ctx.MockServerUri); var order = await client.GetOrderAsync("123"); Assert.NotNull(order); }); } asyncapi_contracts: approach: "Message schema contracts" verification: - "Producer publishes valid messages" - "Consumer can deserialize all message versions" - "Schema registry enforces compatibility"
API Governance
Style Guidelines
api_style_guidelines: naming: resources: - "Use plural nouns (users, orders, products)" - "Use kebab-case for multi-word (order-items)" - "Avoid verbs in resource names" operations: - "operationId: camelCase (getUser, createOrder)" - "Consistent verb usage across APIs" fields: - "camelCase for JSON properties" - "Consistent date format (ISO 8601)" - "Use standard field names (id, createdAt, updatedAt)" structure: versioning: "URL path versioning (/v1/)" pagination: "Cursor-based or offset, consistent approach" errors: "RFC 7807 Problem Details" filtering: "Query parameters with consistent naming" security: authentication: "OAuth 2.0 / API Key as standard" authorization: "Scopes documented in spec" sensitive_data: "Never in URL parameters" documentation: required: - "Summary for every operation" - "Description for complex operations" - "Examples for request/response bodies" - "Error response documentation"
Automated Enforcement
automated_enforcement: linting: tools: - "Spectral (OpenAPI)" - "AsyncAPI Studio" - "Redocly CLI" spectral_rules: | extends: ["spectral:oas", "spectral:asyncapi"] rules: operation-operationId: severity: error operation-summary: severity: error operation-tags: severity: warn info-contact: severity: error response-error-format: description: "Errors must use RFC 7807" severity: error given: "$.paths.*.*.responses[?(@property >= '400')]" then: field: content.application/problem+json function: truthy breaking_change_detection: ci_step: | - name: Check Breaking Changes run: | oasdiff breaking \ --base main:specs/api.yaml \ --revision HEAD:specs/api.yaml \ --fail-on ERR pre_commit_hooks: config: | repos: - repo: local hooks: - id: lint-openapi name: Lint OpenAPI entry: spectral lint specs/**/*.yaml language: node types: [yaml]
API Catalog
api_catalog: purpose: "Central registry of all API contracts" features: discovery: "Find APIs by name, domain, capability" documentation: "Auto-generated from specs" versioning: "Track all versions and changes" dependencies: "Consumer/provider relationships" metrics: "Usage, errors, latency" metadata_per_api: identity: - "Name and description" - "Owner team" - "Domain/capability" lifecycle: - "Current version" - "Status (draft/published/deprecated)" - "Sunset date if deprecated" consumers: - "Registered consumers" - "Usage statistics" quality: - "Documentation score" - "Test coverage" - "Breaking change history" integration: specification_source: "Git repository" ci_cd: "Publish on merge to main" portal: "Developer portal generation"
Validation Checklist
contract_first_checklist: pre_design: - "Consumer use cases documented" - "Resource model defined" - "Authentication/authorization strategy chosen" - "Versioning strategy agreed" specification: - "Valid OpenAPI/AsyncAPI syntax" - "Passes linting rules" - "All operations have operationId" - "Examples provided for complex types" - "Error responses documented" - "Security schemes defined" review: - "Consumer representatives reviewed" - "No unnecessary breaking changes" - "Backward compatibility verified" - "Documentation complete" implementation: - "Generated stubs used" - "Contract tests passing" - "Response validation enabled" - "Schema changes go through spec first" publication: - "Changelog updated" - "Catalog entry created" - "Consumers notified" - "Deprecation warnings if applicable"
References
- Related skill:
- OpenAPI specification authoringopenapi-authoring - Related skill:
- AsyncAPI specification authoringasyncapi-authoring - Related skill:
- Acceptance criteria in Gherkin formatgherkin-authoring
Last Updated: 2025-12-26