## Dlaczego OpenAPI 3.0 to przyszłość dokumentacji API
Każdy developer pracujący z API zna ten ból – dokumentacja która nie odpowiada rzeczywistości. Albo w ogóle jej nie ma. Albo jest napisana ręcznie i nikt jej nie aktualizuje. OpenAPI 3.0 rozwiązuje te problemy fundamentalnie – pozwala opisać API w standardowym formacie, z którego automatycznie generujesz dokumentację, testy i nawet kod klienta.
OpenAPI 3.0 to oficjalna nazwa tego co wcześniej nazywało się „Swagger 3.0”. Standard został znacząco ulepszony względem Swagger 2.0 i jest obecnie najszerzej adoptowanym sposobem opisywania REST API.
Co się nauczysz:
- Podstawy składni OpenAPI 3.0 i kluczowe różnice względem Swagger 2.0
- Jak opisać endpointy, parametry i modele danych w OpenAPI
- Generowanie interaktywnej dokumentacji ze specyfikacji
- Podstawy walidacji requestów i response’ów
- Integrację OpenAPI z popularnymi frameworkami Java
Wymagania wstępne:
- Podstawowa znajomość REST API i HTTP
- Znajomość JSON i YAML
- Doświadczenie z tworzeniem API (Spring Boot mile widziany)
- Zrozumienie koncepcji dokumentacji technicznej
## Co nowego w OpenAPI 3.0
### Kluczowe ulepszenia względem Swagger 2.0
OpenAPI 3.0 wprowadza szereg istotnych ulepszeń:
**Lepsze opisywanie request/response body:**
– Rozdzielenie parametrów od body
– Wsparcie dla różnych formatów media (JSON, XML, form-data)
– Lepsze opisywanie przykładów
**Ulepszone komponenty:**
– Możliwość ponownego wykorzystania większej liczby elementów
– Callbacks dla asynchronicznych API
– Links opisujące powiązania między operacjami
**Większa elastyczność:**
– Wsparcie dla wielu serwerów (dev, staging, prod)
– Lepsze opisywanie bezpieczeństwa
– Rozszerzone możliwości walidacji
## Pierwsza specyfikacja OpenAPI 3.0
Zacznijmy od prostego przykładu API do zarządzania użytkownikami:
openapi: 3.0.2 info: title: User Management API description: Proste API do zarządzania użytkownikami version: 1.0.0 contact: name: Development Team email: dev@company.com servers: - url: https://api.company.com/v1 description: Production server - url: https://staging-api.company.com/v1 description: Staging server - url: http://localhost:8080/v1 description: Development server paths: /users: get: summary: Pobierz listę użytkowników description: Zwraca paginowaną listę wszystkich użytkowników parameters: - name: page in: query description: Numer strony (od 1) required: false schema: type: integer minimum: 1 default: 1 - name: size in: query description: Liczba elementów na stronę required: false schema: type: integer minimum: 1 maximum: 100 default: 20 responses: '200': description: Lista użytkowników content: application/json: schema: $ref: '#/components/schemas/UserList' example: users: - id: 1 email: "john.doe@example.com" firstName: "John" lastName: "Doe" createdAt: "2019-10-20T10:30:00Z" pagination: page: 1 size: 20 total: 150 totalPages: 8 '400': description: Nieprawidłowe parametry content: application/json: schema: $ref: '#/components/schemas/Error' post: summary: Utwórz nowego użytkownika description: Tworzy nowego użytkownika w systemie requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateUserRequest' example: email: "jane.smith@example.com" firstName: "Jane" lastName: "Smith" password: "securePassword123" responses: '201': description: Użytkownik został utworzony content: application/json: schema: $ref: '#/components/schemas/User' '400': description: Nieprawidłowe dane wejściowe content: application/json: schema: $ref: '#/components/schemas/Error' '409': description: Użytkownik o podanym emailu już istnieje content: application/json: schema: $ref: '#/components/schemas/Error' /users/{userId}: get: summary: Pobierz użytkownika po ID parameters: - name: userId in: path required: true description: Unikalny identyfikator użytkownika schema: type: integer format: int64 responses: '200': description: Dane użytkownika content: application/json: schema: $ref: '#/components/schemas/User' '404': description: Użytkownik nie znaleziony content: application/json: schema: $ref: '#/components/schemas/Error' components: schemas: User: type: object required: - id - email - firstName - lastName - createdAt properties: id: type: integer format: int64 description: Unikalny identyfikator użytkownika example: 123 email: type: string format: email description: Adres email użytkownika example: "user@example.com" firstName: type: string minLength: 1 maxLength: 50 description: Imię użytkownika example: "John" lastName: type: string minLength: 1 maxLength: 50 description: Nazwisko użytkownika example: "Doe" createdAt: type: string format: date-time description: Data utworzenia konta example: "2019-10-20T10:30:00Z" CreateUserRequest: type: object required: - email - firstName - lastName - password properties: email: type: string format: email description: Adres email użytkownika firstName: type: string minLength: 1 maxLength: 50 description: Imię użytkownika lastName: type: string minLength: 1 maxLength: 50 description: Nazwisko użytkownika password: type: string minLength: 8 description: Hasło użytkownika (min. 8 znaków) UserList: type: object required: - users - pagination properties: users: type: array items: $ref: '#/components/schemas/User' pagination: $ref: '#/components/schemas/Pagination' Pagination: type: object required: - page - size - total - totalPages properties: page: type: integer description: Aktualna strona size: type: integer description: Liczba elementów na stronę total: type: integer description: Całkowita liczba elementów totalPages: type: integer description: Całkowita liczba stron Error: type: object required: - code - message properties: code: type: string description: Kod błędu example: "VALIDATION_ERROR" message: type: string description: Opis błędu example: "Email address is required"
## Kluczowe różnice względem Swagger 2.0
### Struktura requestBody
Największą zmianą jest sposób opisywania request body:
**Swagger 2.0:**
# Stary sposób - wszystko w parameters parameters: - name: user in: body required: true schema: $ref: '#/definitions/User'
**OpenAPI 3.0:**
# Nowy sposób - oddzielny requestBody requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/User' application/xml: schema: $ref: '#/components/schemas/User'
### Wieloserwerowe środowiska
# OpenAPI 3.0 wspiera wiele serwerów servers: - url: https://api.example.com/v1 description: Production - url: https://staging-api.example.com/v1 description: Staging - url: http://localhost:8080/v1 description: Local development
## Generowanie dokumentacji
### Swagger UI
Najłatwiejszy sposób na wizualizację OpenAPI to Swagger UI:
API Documentation
### Integracja ze Spring Boot
Dodanie OpenAPI do projektu Spring Boot 2.x:
org.springdoc springdoc-openapi-ui 1.2.26
@RestController @RequestMapping("/api/v1/users") @Tag(name = "User Management", description = "Operations related to user management") public class UserController { @GetMapping @Operation(summary = "Get all users", description = "Returns paginated list of users") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Users retrieved successfully", content = @Content(schema = @Schema(implementation = UserList.class))), @ApiResponse(responseCode = "400", description = "Invalid parameters", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntitygetUsers( @Parameter(description = "Page number starting from 1") @RequestParam(defaultValue = "1") int page, @Parameter(description = "Number of items per page") @RequestParam(defaultValue = "20") int size) { UserList users = userService.getUsers(page, size); return ResponseEntity.ok(users); } @PostMapping @Operation(summary = "Create new user", description = "Creates a new user in the system") public ResponseEntity createUser( @RequestBody @Valid CreateUserRequest request) { User user = userService.createUser(request); return ResponseEntity.status(HttpStatus.CREATED).body(user); } }
## Walidacja i testowanie
### Automatyczna walidacja requestów
OpenAPI może służyć do automatycznej walidacji:
@Component public class OpenApiValidator { private final OpenApi3 api; public OpenApiValidator() throws IOException { // Załaduj specyfikację z pliku String spec = Files.readString(Paths.get("src/main/resources/openapi.yaml")); this.api = (OpenApi3) new OpenApiParser().parse(spec, true); } public ValidationReport validateRequest(String path, String method, String body) { Request request = new Request.Builder(path, Method.valueOf(method)) .body(MediaType.parse("application/json"), body) .build(); return api.validateRequest(request); } }
## Narzędzia i ekosystem
### Popularne narzędzia OpenAPI (stan na 2019):
Narzędzie | Zastosowanie | Zalety |
---|---|---|
Swagger UI | Dokumentacja interaktywna | Darmowe, łatwe w użyciu |
Swagger Codegen | Generowanie kodu klienta | Wiele języków programowania |
Postman | Testowanie API | Import OpenAPI, automatyczne testy |
Insomnia | Testowanie API | Dobra alternatywa dla Postman |
Redoc | Dokumentacja statyczna | Lepszy design niż Swagger UI |
Tak, szczególnie dla nowych projektów. OpenAPI 3.0 oferuje lepszą składnię, więcej możliwości i lepsze wsparcie narzędzi. Dla istniejących projektów rozważ migrację gdy planujesz większe zmiany w API.
Zacznij od opisania 1-2 najważniejszych endpointów ręcznie, potem rozważ użycie narzędzi jak springdoc-openapi które generują specyfikację automatycznie z kodu.
YAML jest czytelniejszy dla ludzi, JSON lepszy dla narzędzi. Większość zespołów wybiera YAML do pisania ręcznego, a narzędzia mogą konwertować do JSON gdy potrzeba.
Najlepiej używać podejścia „code-first” z annotacjami (jak springdoc-openapi) lub włączyć walidację specyfikacji do procesu CI/CD żeby wyłapać niezgodności.
Nie, OpenAPI jest przeznaczone dla REST API. GraphQL ma własne narzędzia do introspection i dokumentacji. Nie mieszaj tych dwóch podejść.
Traktuj specyfikację jak kod – używaj Git, semantic versioning i tagów. Zmiany breaking w API powinny zwiększać major version specyfikacji.
Absolutnie! OpenAPI świetnie sprawdza się do dokumentowania wewnętrznych API w microservices. Pomoże zespołom lepiej zrozumieć interfejsy między serwisami.
🚀 Zadanie dla Ciebie
Stwórz kompletną specyfikację OpenAPI 3.0 dla prostego API sklepu internetowego:
- Endpointy do zarządzania produktami (CRUD)
- Endpoint do składania zamówień
- Odpowiednie kody błędów i walidację
- Przynajmniej 3 różne serwery (dev, staging, prod)
Bonus: Użyj Swagger UI do wygenerowania interaktywnej dokumentacji i przetestuj wszystkie endpointy.
## Przydatne zasoby
– [OpenAPI Specification](https://spec.openapis.org/oas/v3.0.2) – oficjalna specyfikacja 3.0.2
– [Swagger Editor](https://editor.swagger.io/) – online edytor specyfikacji
– [Springdoc OpenAPI](https://springdoc.org/) – integracja z Spring Boot
– [OpenAPI Generator](https://openapi-generator.tech/) – generowanie kodu z specyfikacji
– [Redoc](https://github.com/Redocly/redoc) – alternatywna dokumentacja dla OpenAPI
OpenAPI 3.0 to standard który zmieni sposób jak dokumentujesz i myślisz o API. Czy Twoje API są gotowe na przyszłość dokumentacji?