OpenAPI 3.0 – dokumentacja API

TL;DR: OpenAPI 3.0 to nowoczesny standard do opisywania REST API. Zastępuje Swagger 2.0 i oferuje lepszą składnię, więcej możliwości oraz automatyczne generowanie dokumentacji i kodu. Jeśli tworzysz API w 2019 roku, OpenAPI to must-have.

## 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ń:

OpenAPI 3.0 został wydany w lipcu 2017 roku, ale dopiero w 2019 roku narzędzia i biblioteki osiągnęły dojrzałość pozwalającą na szerokie zastosowanie w projektach produkcyjnych.

**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"
Komponenty: W OpenAPI 3.0 sekcja components zastępuje definitions ze Swagger 2.0. Pozwala na definiowanie wielokrotnie używanych elementów: schematów, parametrów, response’ów czy przykładów.

## 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
Pro tip: Wykorzystaj zmienne w URL serwerów: https://{environment}.api.example.com z odpowiednimi wartościami domyślnymi. Pozwala to na jeszcze większą elastyczność.

## 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 ResponseEntity getUsers(
            @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);
    }
}
Springdoc-openapi to popularna biblioteka która automatycznie generuje specyfikację OpenAPI 3.0 z annotacji Spring. W przeciwieństwie do starszego springfox, który wspierał tylko Swagger 2.0.

## 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);
    }
}
Uwaga: Walidacja w runtime może wpływać na wydajność. Rozważ włączanie jej tylko w środowisku development lub dla wybranych endpointów.

## Narzędzia i ekosystem

### Popularne narzędzia OpenAPI (stan na 2019):

NarzędzieZastosowanieZalety
Swagger UIDokumentacja interaktywnaDarmowe, łatwe w użyciu
Swagger CodegenGenerowanie kodu klientaWiele języków programowania
PostmanTestowanie APIImport OpenAPI, automatyczne testy
InsomniaTestowanie APIDobra alternatywa dla Postman
RedocDokumentacja statycznaLepszy design niż Swagger UI

Pułapka: Nie wszystkie narzędzia w pełni wspierają OpenAPI 3.0 w 2019 roku. Sprawdź kompatybilność przed wyborem narzędzia do swojego workflow.
Czy warto migrować ze Swagger 2.0 do OpenAPI 3.0?

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.

Jak zacząć z OpenAPI jeśli mam już gotowe 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 czy JSON dla specyfikacji OpenAPI?

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.

Jak utrzymać specyfikację OpenAPI w sync z kodem?

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.

Czy OpenAPI nadaje się do GraphQL?

Nie, OpenAPI jest przeznaczone dla REST API. GraphQL ma własne narzędzia do introspection i dokumentacji. Nie mieszaj tych dwóch podejść.

Jak wersjonować specyfikację OpenAPI?

Traktuj specyfikację jak kod – używaj Git, semantic versioning i tagów. Zmiany breaking w API powinny zwiększać major version specyfikacji.

Czy mogę używać OpenAPI dla internal API?

Absolutnie! OpenAPI świetnie sprawdza się do dokumentowania wewnętrznych API w microservices. Pomoże zespołom lepiej zrozumieć interfejsy między serwisami.

Następne kroki:

Teraz gdy znasz podstawy OpenAPI 3.0, warto zgłębić:

🚀 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?

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Przewijanie do góry