# Generate Contract

> Generate comprehensive API contracts for consumer-driven contract testing

- Skill: `tools-only/generate-contract` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds add tools-only/generate-contract`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/generate-contract/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/tools-only/generate-contract

---

<!-- DESIGN DECISIONS -->
<!-- API contracts enable safe microservice evolution by ensuring compatibility
     between consumers and providers. This command generates contracts in multiple
     formats (Pact, Spring Cloud Contract, OpenAPI) to support various testing frameworks. -->

<!-- ALTERNATIVES CONSIDERED -->
<!-- Manual contract writing: Rejected due to error-prone nature and time consumption
     Schema-only validation: Rejected as it doesn't capture behavioral contracts
     Record-replay testing: Rejected as it doesn't enable consumer-driven development -->

# Generate API Contract

Creates comprehensive API contracts for consumer-driven contract testing, enabling safe evolution of microservices by validating interactions between service consumers and providers. Supports Pact, Spring Cloud Contract, and OpenAPI specifications with automated verification and CI/CD integration.

## When to Use

Use this command when:
- Building microservices that need to evolve independently
- Implementing consumer-driven contract testing (CDCT)
- Preventing breaking changes between API versions
- Setting up automated compatibility testing in CI/CD
- Documenting API expectations between teams
- Migrating from monolithic to microservice architecture
- Establishing service boundaries and contracts

Do NOT use this command for:
- Internal function testing (use unit tests instead)
- UI testing (use end-to-end tests)
- Performance testing (use load testing tools)
- Security testing (use security scanning tools)

## Prerequisites

Before running this command, ensure:
- [ ] API endpoints are defined (at least conceptually)
- [ ] Consumer and provider services are identified
- [ ] Testing framework is chosen (Pact, Spring Cloud Contract, etc.)
- [ ] API documentation exists or requirements are clear
- [ ] Version control is set up for contract storage

## Process

### Step 1: Analyze API Requirements
The command examines your API specifications to generate appropriate contracts:
- Identifies HTTP methods and endpoints
- Extracts request/response schemas
- Determines required headers and parameters
- Captures validation rules and constraints
- Notes authentication requirements

### Step 2: Generate Contract Definitions
Based on the analysis, creates contract files that include:
- Consumer expectations (what the consumer needs)
- Provider capabilities (what the provider offers)
- Interaction definitions (request/response pairs)
- State management (preconditions for tests)
- Metadata for versioning and identification

### Step 3: Create Verification Tests
Generates test code to verify contracts:
- Consumer-side tests to ensure correct API usage
- Provider-side tests to verify implementation
- Mock server configurations for isolated testing
- Integration points for CI/CD pipelines
- Breaking change detection logic

### Step 4: Configure Contract Management
Sets up infrastructure for contract lifecycle:
- Contract versioning strategies
- Pact Broker or contract repository configuration
- CI/CD pipeline integration scripts
- Webhook configurations for automated testing
- Documentation generation from contracts

## Output Format

The command generates multiple files based on your chosen framework:

```
api-contracts/
├── consumers/
│   ├── [consumer-name]/
│   │   ├── pacts/
│   │   │   └── [consumer]-[provider].json
│   │   └── tests/
│   │       └── contract.test.js
├── providers/
│   ├── [provider-name]/
│   │   ├── contracts/
│   │   │   └── [provider]-contract.groovy
│   │   └── tests/
│   │       └── contract-verification.test.js
├── shared/
│   ├── schemas/
│   │   └── api-schema.json
│   └── states/
│       └── provider-states.js
└── docs/
    └── contract-documentation.md
```

**Output Files Explained:**
- `pacts/`: Pact contract files in JSON format
- `contracts/`: Spring Cloud Contract definitions in Groovy/YAML
- `tests/`: Generated test files for contract verification
- `schemas/`: Shared schema definitions (JSON Schema, OpenAPI)
- `states/`: Provider state setup for test scenarios
- `docs/`: Human-readable contract documentation

## Examples

### Example 1: REST API User Service Contract

**Scenario:** Generate contract for a user service with CRUD operations

**User Input:**
```
/generate-contract --service user-api --consumer mobile-app --framework pact
```

**Generated Pact Contract:**
```json
{
  "consumer": {
    "name": "mobile-app"
  },
  "provider": {
    "name": "user-api"
  },
  "interactions": [
    {
      "description": "a request to get a user",
      "providerState": "user with ID 123 exists",
      "request": {
        "method": "GET",
        "path": "/api/users/123",
        "headers": {
          "Accept": "application/json",
          "Authorization": "Bearer [token]"
        }
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Type": "application/json"
        },
        "body": {
          "id": "123",
          "email": "[email protected]",
          "name": "John Doe",
          "createdAt": "2025-01-15T10:00:00Z"
        },
        "matchingRules": {
          "$.body.email": {
            "match": "type"
          },
          "$.body.createdAt": {
            "match": "regex",
            "regex": "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z"
          }
        }
      }
    },
    {
      "description": "a request to create a user",
      "providerState": "no user exists",
      "request": {
        "method": "POST",
        "path": "/api/users",
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "Bearer [token]"
        },
        "body": {
          "email": "[email protected]",
          "name": "Jane Smith",
          "password": "SecurePass123!"
        }
      },
      "response": {
        "status": 201,
        "headers": {
          "Content-Type": "application/json",
          "Location": "/api/users/124"
        },
        "body": {
          "id": "124",
          "email": "[email protected]",
          "name": "Jane Smith",
          "createdAt": "2025-01-15T11:00:00Z"
        }
      }
    }
  ],
  "metadata": {
    "pactSpecification": {
      "version": "2.0.0"
    }
  }
}
```

**Generated Consumer Test:**
```javascript
// consumer-tests/user-api.test.js
const { Pact } = require('@pact-foundation/pact');
const { getUserById, createUser } = require('../src/api-client');

describe('User API Consumer Tests', () => {
  const provider = new Pact({
    consumer: 'mobile-app',
    provider: 'user-api',
    port: 8080,
    log: path.resolve(process.cwd(), 'logs', 'pact.log'),
    dir: path.resolve(process.cwd(), 'pacts'),
    logLevel: 'warn'
  });

  beforeAll(() => provider.setup());
  afterEach(() => provider.verify());
  afterAll(() => provider.finalize());

  describe('GET /api/users/:id', () => {
    it('should return a user when user exists', async () => {
      // Arrange
      await provider.addInteraction({
        state: 'user with ID 123 exists',
        uponReceiving: 'a request to get a user',
        withRequest: {
          method: 'GET',
          path: '/api/users/123',
          headers: {
            'Accept': 'application/json',
            'Authorization': 'Bearer valid-token'
          }
        },
        willRespondWith: {
          status: 200,
          headers: {
            'Content-Type': 'application/json'
          },
          body: {
            id: '123',
            email: '[email protected]',
            name: 'John Doe',
            createdAt: '2025-01-15T10:00:00Z'
          }
        }
      });

      // Act
      const user = await getUserById('123', 'valid-token');

      // Assert
      expect(user.id).toBe('123');
      expect(user.email).toBe('[email protected]');
    });
  });
});
```

---

### Example 2: Spring Cloud Contract for Payment Service

**Scenario:** Generate contract for payment processing service

**User Input:**
```
/contract --service payment-service --consumer checkout-app --framework spring
```

**Generated Spring Cloud Contract (Groovy):**
```groovy
// contracts/payment/process-payment.groovy
package contracts.payment

import org.springframework.cloud.contract.spec.Contract

Contract.make {
    description "Process a payment transaction"
    label "process_payment"

    request {
        method POST()
        url "/api/payments"
        headers {
            contentType(applicationJson())
            header("Authorization", "Bearer ${anyNonEmptyString()}")
        }
        body([
            amount: 99.99,
            currency: "USD",
            customerId: anyUuid(),
            paymentMethod: [
                type: "CARD",
                cardNumber: regex('[0-9]{16}'),
                expiryMonth: regex('(0[1-9]|1[0-2])'),
                expiryYear: regex('20[2-9][0-9]'),
                cvv: regex('[0-9]{3}')
            ],
            orderId: anyUuid()
        ])
    }

    response {
        status 200
        headers {
            contentType(applicationJson())
        }
        body([
            transactionId: anyUuid(),
            status: "APPROVED",
            amount: 99.99,
            currency: "USD",
            processedAt: anyIso8601DateTime(),
            authorizationCode: regex('[A-Z0-9]{6}')
        ])
    }
}
```

**Generated Provider Verification Test:**
```java
// PaymentContractVerificationTest.java
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@AutoConfigureWebTestClient
public class PaymentContractVerificationTest {

    @LocalServerPort
    private int port;

    @MockBean
    private PaymentService paymentService;

    @TestTarget
    public final Target target = new SpringBootHttpTarget();

    @Before
    public void setup() {
        RestAssuredMockMvc.webAppContextSetup(context);
    }

    @State("payment service is available")
    public void paymentServiceAvailable() {
        // Setup mock responses
        PaymentResponse response = PaymentResponse.builder()
            .transactionId(UUID.randomUUID().toString())
            .status("APPROVED")
            .amount(99.99)
            .currency("USD")
            .processedAt(Instant.now())
            .authorizationCode("ABC123")
            .build();

        when(paymentService.processPayment(any(PaymentRequest.class)))
            .thenReturn(response);
    }
}
```

---

### Example 3: OpenAPI Contract with Validation

**Scenario:** Generate OpenAPI contract with request/response validation

**User Input:**
```
/generate-contract --service product-catalog --format openapi --with-validation
```

**Generated OpenAPI Specification:**
```yaml
openapi: 3.0.3
info:
  title: Product Catalog API Contract
  version: 1.0.0
  description: Contract for product catalog service interactions

paths:
  /api/products:
    get:
      operationId: getProducts
      summary: List products with pagination
      parameters:
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductList'
              examples:
                success:
                  value:
                    products:
                      - id: "prod-123"
                        name: "Widget Pro"
                        price: 29.99
                        stock: 150
                    pagination:
                      page: 1
                      limit: 20
                      total: 45

components:
  schemas:
    ProductList:
      type: object
      required:
        - products
        - pagination
      properties:
        products:
          type: array
          items:
            $ref: '#/components/schemas/Product'
        pagination:
          $ref: '#/components/schemas/Pagination'

    Product:
      type: object
      required:
        - id
        - name
        - price
        - stock
      properties:
        id:
          type: string
          pattern: '^prod-[a-z0-9]+$'
        name:
          type: string
          minLength: 1
          maxLength: 200
        price:
          type: number
          minimum: 0
          multipleOf: 0.01
        stock:
          type: integer
          minimum: 0
```

## Error Handling

### Error: Missing API Documentation
**Symptoms:** No OpenAPI spec or API documentation available
**Cause:** API not yet documented or in early development
**Solution:**
```
The command will guide you through interactive API definition:
- Define endpoints and methods
- Specify request/response formats
- Add validation rules
- Generate initial documentation
```
**Prevention:** Document APIs as part of development process

### Error: Incompatible Contract Versions
**Symptoms:** Consumer and provider contracts don't match
**Cause:** Services evolved independently without coordination
**Solution:**
```
Contract Version Migration:
1. Identify breaking changes
2. Create compatibility layer
3. Version contracts appropriately
4. Implement gradual migration
```

### Error: Contract Verification Failure
**Symptoms:** Provider tests fail against consumer contracts
**Cause:** Implementation doesn't match contract expectations
**Solution:**
```
Debug Contract Mismatches:
1. Review failed interaction details
2. Check request/response differences
3. Update implementation or contract
4. Re-run verification tests
```

## Configuration Options

The contract generation can be customized with:

### Option: `--framework`
- **Purpose:** Choose contract testing framework
- **Values:** `pact`, `spring`, `openapi`, `postman`
- **Default:** `pact`
- **Example:** `/contract --framework spring`

### Option: `--strict`
- **Purpose:** Enable strict validation rules
- **Default:** false
- **Example:** `/contract --strict`

### Option: `--version`
- **Purpose:** Specify contract version
- **Default:** Auto-incremented
- **Example:** `/contract --version 2.0.0`

## Best Practices

✅ **DO:**
- Version your contracts alongside API versions
- Run contract tests in CI/CD pipeline
- Use contract broker for centralized management
- Document breaking changes clearly
- Test both happy path and error scenarios

❌ **DON'T:**
- Modify generated contracts manually without updating source
- Skip contract verification before deployment
- Use contracts as replacement for all testing
- Ignore contract test failures

💡 **TIPS:**
- Start with consumer-driven contracts for better API design
- Use semantic versioning for contract versions
- Implement backwards compatibility when possible
- Share contracts between teams early in development

## Related Commands

- `/api-versioning-manager` - Manage API versions and migrations
- `/api-documentation-generator` - Generate comprehensive API docs
- `/api-mock-server` - Create mock servers from contracts
- `/api-testing-suite` - Generate integration test suites

## Performance Considerations

- **Generation time:** 2-5 seconds for typical API
- **Contract size:** Usually <100KB per service pair
- **Test execution:** Milliseconds for contract tests
- **Scaling:** Supports hundreds of service interactions

## Security Notes

⚠️ **Security Considerations:**
- Never include real credentials in contracts
- Use token placeholders for authentication
- Sanitize sensitive data in examples
- Store contracts in version control securely
- Implement contract access controls in broker

## Troubleshooting

### Issue: Contracts not being published
**Solution:** Check broker credentials and network connectivity

### Issue: Mock server not starting
**Solution:** Verify port availability and permissions

### Issue: Contract tests timing out
**Solution:** Increase timeout values for slow services

### Getting Help
- Pact documentation: https://docs.pact.io
- Spring Cloud Contract: https://spring.io/projects/spring-cloud-contract
- OpenAPI specification: https://swagger.io/specification/

## Version History

- **v2.0.0** - Complete rewrite with multi-framework support
- **v1.0.0** - Initial Pact-only implementation

---

*Last updated: 2025-10-11*
*Quality score: 9+/10*
*Tested with: Pact v10, Spring Cloud Contract v4, OpenAPI v3.0.3*
