Skip to content
Back to skills

Openapi First

ASecurity

Use when the project follows API-first / OpenAPI-first approach: generating controller interfaces, DTOs, and clients from an OpenAPI spec. Use when you see openapi.yaml, openapi-generator-maven-plugin, or ApiDelegate pattern in the project.

  • 272 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 6, 2026
ai-agentsgojavaspringgitapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned September 6, 2026

npx -y skills add rrezartprebreza/spring-boot-skills --skill openapi-first --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Openapi First?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Openapi First
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rrezartprebreza-openapi-first-spring-boot-skills/badge)](https://www.skillsdirectory.com/skills/rrezartprebreza-openapi-first-spring-boot-skills)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: openapi-first
description: >
  Use when the project follows API-first / OpenAPI-first approach: generating controller
  interfaces, DTOs, and clients from an OpenAPI spec. Use when you see openapi.yaml,
  openapi-generator-maven-plugin, or ApiDelegate pattern in the project.
---

# OpenAPI-First Development

## Maven Plugin Setup

```xml
<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>7.5.0</version>
    <executions>
        <execution>
            <goals><goal>generate</goal></goals>
            <configuration>
                <inputSpec>${project.basedir}/src/main/resources/openapi.yaml</inputSpec>
                <generatorName>spring</generatorName>
                <apiPackage>com.example.api</apiPackage>
                <modelPackage>com.example.api.model</modelPackage>
                <configOptions>
                    <delegatePattern>true</delegatePattern>      <!-- implement delegate, not controller -->
                    <interfaceOnly>false</interfaceOnly>
                    <useSpringBoot3>true</useSpringBoot3> <!-- still the OpenAPI Generator Jakarta/Spring 6+ switch -->
                    <useTags>true</useTags>
                    <dateLibrary>java8</dateLibrary>
                    <serializationLibrary>jackson</serializationLibrary>
                    <openApiNullable>false</openApiNullable>
                    <skipDefaultInterface>true</skipDefaultInterface>
                </configOptions>
                <generateSupportingFiles>true</generateSupportingFiles>
                <output>${project.build.directory}/generated-sources/openapi</output>
            </configuration>
        </execution>
    </executions>
</plugin>
```

## OpenAPI Spec Example

```yaml
# src/main/resources/openapi.yaml
openapi: 3.0.3
info:
  title: Order Service API
  version: 1.0.0

paths:
  /api/v1/orders:
    post:
      tags: [Orders]
      operationId: createOrder
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrderRequest'
      responses:
        '201':
          description: Order created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderResponse'
        '400':
          $ref: '#/components/responses/ValidationError'

    get:
      tags: [Orders]
      operationId: listOrders
      parameters:
        - name: page
          in: query
          schema: { type: integer, default: 0 }
        - name: size
          in: query
          schema: { type: integer, default: 20 }
      responses:
        '200':
          description: Paginated orders
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderPage'

components:
  schemas:
    CreateOrderRequest:
      type: object
      required: [customerEmail, items]
      properties:
        customerEmail:
          type: string
          format: email
        items:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/OrderItemRequest'

    OrderResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        status:
          type: string
          enum: [PENDING, PROCESSING, SHIPPED, DELIVERED, CANCELLED]
        customerEmail:
          type: string
        createdAt:
          type: string
          format: date-time

  responses:
    ValidationError:
      description: Validation failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
```

## Implementing the Delegate

```java
// Generated: OrdersApi interface with delegate
// Your implementation — never modify generated files

@Service
@RequiredArgsConstructor
public class OrdersApiDelegateImpl implements OrdersApiDelegate {

    private final OrderService orderService;

    @Override
    public ResponseEntity<OrderResponse> createOrder(CreateOrderRequest request) {
        Order order = orderService.createOrder(request);
        return ResponseEntity.status(HttpStatus.CREATED)
            .body(OrderApiMapper.toResponse(order));
    }

    @Override
    public ResponseEntity<OrderPage> listOrders(Integer page, Integer size) {
        Page<Order> orders = orderService.findAll(PageRequest.of(page, size));
        return ResponseEntity.ok(OrderApiMapper.toPage(orders));
    }
}
```

## .gitignore — Never Commit Generated Files

```gitignore
target/generated-sources/openapi/
```

## Gotchas
- Agent modifies generated controller files — NEVER modify generated code, implement delegate
- Agent generates code without `useSpringBoot3=true` — uses old `javax.*` imports; despite the name, this is still the OpenAPI Generator flag for Jakarta/Spring 6+ generation
- Agent commits generated sources — add to `.gitignore`, generate on build
- Agent skips `skipDefaultInterface=true` — generates default methods that hide missing impls
- Agent mixes generated models with hand-written models — keep them separate

Files in this skill

  • SKILL.md5.1 KB
  • agents/openai.yaml192 B
  • examples/bad-delegate-impl.java1.5 KB
  • examples/good-delegate-impl.java1.6 KB
  • templates/openapi.yaml4.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.