Openapi first
Skill rrezartprebreza/spring-boot-skills/skills/spring-boot-4/openapi-first
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.From its SKILL.md
npx -y skills add rrezartprebreza/spring-boot-skills --skill openapi-firstAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
5.1 KB, ~1.0k tokens by cl100k_base, as published. Nobody here has run it
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> <!-- 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
# 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
// 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 oldjavax.*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
What ships with it: 3 files
7.3 KB alongside SKILL.md
examples/
- bad-delegate-impl.java1.5 KB
- good-delegate-impl.java1.6 KB
templates/
- openapi.yaml4.1 KB
Gives 0 of the 12 instructions most api reference skills give in ~1.0k tokens
Counted across 159 of the 198 authors here whose files we hold, read 2026-09-06
- Document all possible error responsesin 14 of 159, across 7 files
- Create OpenAPI 3.0 compliant specificationsin 13 of 159, across 7 files
- Use $ref for reusable componentsin 12 of 159, across 6 files
- Include example requests and responsesin 11 of 159, across 5 files
- Group endpoints logically with tagsin 11 of 159, across 5 files
- Document all endpoints with descriptions and examplesin 10 of 159, across 4 files
- Define request and response schemas accuratelyin 9 of 159, across 3 files
- Include authentication and security schemesin 8 of 159, across 2 files
- Provide clear examples for all operationsin 8 of 159, across 2 files
- Use descriptive summaries and descriptionsin 8 of 159, across 2 files
- Use clear operation IDsin 8 of 159, across 2 files
- Include parameter types and descriptionsin 7 of 159, across 5 files
Said here and by no other author read
- Configure openapi-generator-maven-plugin in the build
- Enable the delegate pattern in generator config
- Implement delegate classes, not generated controllers
- Set useSpringBoot3=true
- Set skipDefaultInterface=true
- Add generated sources to .gitignore
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.