Skip to content
alyn
rrezartprebreza

Openapi First skill

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.

$npx skills add rrezartprebreza/spring-boot-skills --skill openapi-first
View this skill on GitHubrrezartprebreza/spring-boot-skills/skills/spring-boot-3/openapi-first/SKILL.md
Pack stars
353
Pack installs
3k
Alyn Score
56/99
Updated
4 h ago
License
MIT
– views – installs via Alyn

rrezartprebreza

Openapi First

Install Openapi First

Pick your agent. Every command is ready to paste.

$npx skills add rrezartprebreza/spring-boot-skills --skill openapi-first

The open skills CLI detects your agents (Claude Code, Cursor, Codex and 70+ more) and installs to the right folder. Add -g to install globally.

01

Install it

Run the command above, or upload the folder in Claude.

02

Ask naturally

Describe the task. Your agent loads openapi-first when the request matches its description.

03

Name it if needed

If it does not trigger, say “use the openapi-first skill”. In Codex, type $openapi-first.

The skill itself

SKILL.md

FolderGitHub

OpenAPI-First Development

Maven Plugin Setup

<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>
                    <useTags>true</useTags>
                    <dateLibrary>java8</dateLibrary>
                    <openApiNullable>false</openApiNullable>
                    <skipDefaultInterface>false</skipDefaultInterface> <!-- must stay false with delegatePattern: the controller instantiates a no-op delegate -->
                </configOptions>
                <!-- NOT generateSupportingFiles=true: that adds a second @SpringBootApplication main class
                     (repackage fails: "Unable to find a single main class") and a SpringDocConfiguration -->
                <supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate>
                <modelNameSuffix>Dto</modelNameSuffix> <!-- OrderDto, not Order: no clash with domain types -->
                <output>${project.build.directory}/generated-sources/openapi</output>
            </configuration>
        </execution>
    </executions>
</plugin>

OpenAPI Spec Example

# 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

    OrderItemRequest:
      type: object
      required: [productId, quantity]
      properties:
        productId:
          type: string
          format: uuid
        quantity:
          type: integer
          minimum: 1

    OrderPage:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/OrderResponse'
        page:
          type: integer
        size:
          type: integer
        totalElements:
          type: integer
          format: int64

    ApiError:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
        details:
          type: array
          items:
            type: string

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

Implementing the Delegate

// 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

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
  • Agent commits generated sources — add to .gitignore, generate on build
  • Agent sets skipDefaultInterface=true with delegatePattern=true — the generated controller instantiates a no-op delegate, so it stops compiling; keep it false and cover every operation with a contract test
  • Agent sets generateSupportingFiles=true — generates a second @SpringBootApplication and SpringDoc config; list only ApiUtil.java in supportingFilesToGenerate
  • Agent mixes generated models with hand-written models — keep them separate

Tips for Openapi First

  • • Start a fresh session after installing so your agent picks up the new skill.
  • • It bundles reference files. The agent reads them only when needed, so they cost no context until then.
  • • It is part of a pack with 30 skills. Install only the ones you need with --skill to keep triggers precise.
  • • If two skills overlap, mention the one you want by name.

Questions about Openapi First

What does the Openapi First skill do?

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.

How do I install Openapi First?

Run "npx skills add rrezartprebreza/spring-boot-skills --skill openapi-first" in your project. The skills CLI installs it for Claude Code, Cursor, Codex and 70+ other agents. In Claude on the web, upload the skill folder as a ZIP under Customize > Skills.

Does Openapi First work in Cursor and Codex?

Yes. Openapi First uses the open SKILL.md format, so it works in Claude Code, Claude, Cursor, OpenAI Codex, Gemini CLI, GitHub Copilot and other agents that support agent skills.

Is Openapi First free?

Openapi First is open source on GitHub under the MIT license. It is free to install; check the license before commercial use.

Who made Openapi First?

Openapi First is published by rrezartprebreza in the rrezartprebreza/spring-boot-skills repository, together with 29 other skills.

Similar skills. From other creators.