---
# System prepended metadata

title: Swagger
tags: [swagger, api doc, api, '2021', design]

---

# Swagger

> 一系列的 open-source 工具用來建立 OpenAPI 規格包含設計、建立、寫文件等等

- [範例](https://editor.swagger.io/?_ga=2.153179131.213900886.1632707085-1310170969.1632104466)
- [DOC](https://swagger.io/docs/specification/about/)


# 工具

- [Swagger Editor](https://editor.swagger.io/?_ga=2.185586413.577658464.1632832418-1310170969.1632104466) - 編輯 openAPI 規格
- [Swagger UI](https://swagger.io/tools/swagger-ui/) - 顯示 openAPI 規格的互動式API文件
- [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) - 建立 server studs 和 client libraries

# 結構

- swagger
- info 
    - description
    - version
    - title
    - termsOfService
    - contact
        - email
    - license
        - name
        - url
- host
- basePath
- tags
    - name
    - description
    - externalDocs
        - description
        - url
- schemes
- paths
    - url
        - http method
            -  tags
            -  summary
            -  description
            -  operationId
            -  consumes
            -  produces
            -  parameters
                -  in
                -  name
                -  description
                -  required
                -  schema
            -  responses
                -  http status code
                    - description
            -  security
                -  auth name
                    -  action
- securityDefinitions
    - auth name
        - type
        - authorizationUrl
        - flow
        - scopes
            - action 
- definitions
    - model name
        - type
        - properties
            - property name
                -  type
                -  format
                -  enum
                -  items(type = array)
                -  default
        - xml
            - name

# 語法

## Metadata

- openapi: 3.0.0 // OpenAPI version
- info:
    - title: API 名稱
    - description: 更多API的描述
    - version: API 版本 ex: 1.0-beta or 2017-07-25

## Servers

網址
```
https://api.example.com/v1/users?role=admin&status=active
\________________________/\____/ \______________________/
         server URL       endpoint    query parameters
                            path
```


- server url format - scheme://host[:port][/path]
- servers:
    - url: API server 的網址
    - description: 這台機器的描述像是 staging, production..

### Server Templating 

> 當多個 server 網址中有一些部分是不一樣的時候

```yaml=
servers:
  - url: https://{customerId}.saas-app.com:{port}/v2
    variables:
      customerId:
        default: demo
        description: Customer ID assigned by the service provider
      port:
        enum:
          - '443'
          - '8443'
        default: '443'
```

## Paths

- 獨立的一個 endpoints

```yaml=
paths:
  /users:
    get:
      summary: Returns a list of users.
      description: Optional extended description in CommonMark or HTML
      responses:
        '200':
          description: A JSON array of user names
          content:
            application/json:
              schema: 
                type: array
                items: 
                  type: string
```

### Path Templating

```yaml=
/users/{id}
/organizations/{orgId}/members/{memberId}
/report.{format}
```

### Operations

- get
- post
- put
- patch
- delete
- head
- options 
- trace

### operationId

> 選擇性的 unique string 用來辨識 operation

### Deprecated Operations

這個 url 不會再用了

```yaml=
/pet/findByTags:
  get:
    deprecated: true
```


## Parameters

### path

```yaml=
 /users/{id}
 
 
 paths:
  /users/{id}:
    get:
      parameters:
        - in: path
          name: id   # Note the name is the same as in the path
          required: true
          schema:
            type: integer
            minimum: 1
          description: The user ID
```

### query string

```yaml=
/users?role=admin

parameters:
        - in: query
          name: offset
          schema:
            type: integer
          description: The number of items to skip before starting to collect the result set
        - in: query
          name: limit
          schema:
            type: integer
          description: The numbers of items to return
```

### headers

```yaml=
 X-MyHeader: Value
 
 paths:
  /ping:
    get:
      summary: Checks if the server is alive
      parameters:
        - in: header
          name: X-Request-ID
          schema:
            type: string
            format: uuid
          required: true
```

### cookie

```yaml=
Cookie: debug=0; csrftoken=BUSe35dohU3O1MZvDCU

      parameters:
        - in: cookie
          name: debug
          schema:
            type: integer
            enum: [0, 1]
            default: 0
        - in: cookie
          name: csrftoken
          schema:
            type: string
```


### Required and Optional Parameters

> Required 代表這個參數是否一定要帶

### Default Parameter Values

```yaml=
schema:
    type: integer
    minimum: 1
    maximum: 100
    default: 20
```

### Enum Parameters

```yaml=
schema:
    type: string
    enum:
       - available
       - pending
       - sold
```

### Constant Parameters

```yaml=
schema:
    type: string
    enum:
        - now
```

### Empty-Valued  Parameters

```yaml=
parameters:
    - in: query
      name: metadata
      schema:
          type: boolean
      allowEmptyValue: true  # 
```

### Nullable Parameters

```yaml=
schema:
    type: integer
    format: int32
    nullable: true
```

### Parameter Examples

```yaml=
      parameters:
        - in: query
          name: ids
          description: One or more IDs
          required: true
          schema:
            type: array
            items:
              type: integer
          style: form
          explode: false
          examples:
            oneId:
              summary: Example of a single ID
              value: [5]   # ?ids=5
            multipleIds:
              summary: Example of multiple IDs
              value: [1, 5, 7]   # ?ids=1,5,7
```

### Deprecated Parameters

```yaml=
        - in: query
          name: format
          required: true
          schema:
            type: string
            enum: [json, xml, yaml]
          deprecated: true
          description: Deprecated, use the appropriate `Accept` header instead.
```

### Common Parameters

```yaml=
paths:
  /user/{id}:
    parameters:
      - in: path
        name: id
        schema:
          type: integer
        required: true
        description: The user ID
    get:
      summary: Gets a user by ID
      ...
    patch:
      summary: Updates an existing user with the specified ID
      ...
    delete:
      summary: Deletes the user with the specified ID
      ...
```

### Common Parameters for Various Paths

```yaml=
components:
  parameters:
    offsetParam:  # <-- Arbitrary name for the definition that will be used to refer to it.
                  # Not necessarily the same as the parameter name.
      in: query
      name: offset
      required: false
      schema:
        type: integer
        minimum: 0
      description: The number of items to skip before starting to collect the result set.
    limitParam:
      in: query
      name: limit
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 50
        default: 20
      description: The numbers of items to return.
paths:
  /users:
    get:
      summary: Gets a list of users.
      parameters:
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: OK
  /teams:
    get:
      summary: Gets a list of teams.
      parameters:
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: OK
```


## Request Body

```yaml=
paths:
  /pets:
    post:
      summary: Add a new pet
      requestBody:
        description: Optional description in *Markdown*
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
          application/xml:
            schema:
              $ref: '#/components/schemas/Pet'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PetForm'
          text/plain:
            schema:
              type: string
      responses:
        '201':
          description: Created
```

## Responses

```yaml=
paths:
  /users:
    get:
      summary: Get all users
      responses:
        '200':
          description: A list of users
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrayOfUsers'
            application/xml:
              schema:
                $ref: '#/components/schemas/ArrayOfUsers'
            text/plain:
              schema:
                type: string
  # This operation returns image
  /logo:
    get:
      summary: Get the logo image
      responses:
        '200':
          description: Logo image in PNG format
          content:
            image/png:
              schema:
                type: string
                format: binary
```

### HTTP Status Codes

```yaml=
      responses:
        '200':
          description: OK
        '400':
          description: Bad request. User ID must be an integer and larger than 0.
        '401':
          description: Authorization information is missing or invalid.
        '404':
          description: A user with the specified ID was not found.
        '5XX':
          description: Unexpected error.
```

### Response Body

```yaml=
      responses:
        '200':
          description: A User object
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                    description: The user ID.
                  username:
                    type: string
                    description: The user name.
```

### Response That Returns a File

```yaml=
paths:
  /report:
    get:
      summary: Returns the report in the PDF format
      responses:
        '200':
          description: A PDF file
          content:
            application/pdf:
              schema:
                type: string
                format: binary
```

### Response Headers

```yaml=
HTTP 1/1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 2016-10-12T11:00:00Z
```

### Default Response

```yaml=
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        # These two error responses have the same schema
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error
```

### Reusing Responses

```yaml=
paths:
  /users:
    get:
      summary: Gets a list of users.
      response:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrayOfUsers'
        '401':
          $ref: '#/components/responses/Unauthorized'   # <-----
  /users/{id}:
    get:
      summary: Gets a user by ID.
      response:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '401':
          $ref: '#/components/responses/Unauthorized'   # <-----
        '404':
          $ref: '#/components/responses/NotFound'       # <-----
# Descriptions of common components
components:
  responses:
    NotFound:
      description: The specified resource was not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    # Schema for error response body
    Error:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
      required:
        - code
        - message
```


## Media Types

> request 或 response 的資料格式

類型範例
```yaml=
application/json
application/xml
application/x-www-form-urlencoded
multipart/form-data
text/plain; charset=utf-8
text/html
application/pdf
image/png

application/vnd.mycompany.myapp.v2+json
application/vnd.ms-excel
application/vnd.openstreetmap.data+xml
application/vnd.github-issue.text+json
application/vnd.github.v3.diff
image/vnd.djvu
```

### 多個 media type

```yaml=
paths:
  /employees:
    get:
      summary: Returns a list of employees.
      responses:
        '200':      # Response
          description: OK
          content:  # Response body
            application/json:   # One of media types
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  name:
                    type: string
                  fullTime: 
                    type: boolean
            application/xml:    # Another media types
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  name:
                    type: string
                  fullTime: 
                    type: boolean
```


## Input and Output Models

> `components/schemas` 定義常見的資料格式


範例
```yaml=
components:
  schemas:
    User:
      properties:
        id:
          type: integer
        name:
          type: string
      # Both properties are required
      required:  
        - id
        - name 
```

使用
```yaml=
schema:
    $ref: '#/components/schemas/User'
```

## Authentication

> `securitySchemes` 和 `security ` 描述驗證的方法

範例
```yaml=
components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
    BearerAuth:
      type: http
      scheme: bearer 
security:
  - BasicAuth: []
```

使用
```yaml=
/pet/{petId}:
    delete:
        security:
            - petstore_auth:
                - "write:pets"
                - "read:pets"
```

## Data Models (Schemas)

[Data Models](https://swagger.io/docs/specification/data-models/)

## Adding Examples

```yaml=
// 單一
parameters:
  - in: query
    name: status
    schema:
      type: string
      enum: [approved, pending, closed, new]
      example: approved     # Example of a parameter value
      
      
// 多個

parameters:
  - in: query
    name: limit
    schema:
      type: integer
      maximum: 50
    examples:       # Multiple examples
      zero:         # Distinct name
        value: 0    # Example value
        summary: A sample limit value  # Optional description
      max: # Distinct name
        value: 50   # Example value
        summary: A sample limit value  # Optional description
```

### Request and Response Body Examples

```yaml=
paths:
  /users:
    post:
      summary: Adds a new user
      requestBody:
        content:
          application/json:
            schema:      # Request body contents
              type: object
              properties:
                id:
                  type: integer
                name:
                  type: string
              example:   # Sample object
                id: 10
                name: Jessica Smith
      responses:
        '200':
          description: OK
```

### Object and Property Examples

```yaml=

// property-levle
components:
  schemas:
    User:    # Schema name
      type: object
      properties:
        id:
          type: integer
          format: int64
          example: 1          # Property example
        name:
          type: string
          example: New order  # Property example
          
// object-level
components:
  schemas:
    User:       # Schema name
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
      example:   # Object-level example
        id: 1
        name: Jessica Smith

```

### Array Example

```yaml=
omponents:
  schemas:
    ArrayOfInt:
      type: array
      items:
        type: integer
        format: int64
        example: 1
        
components:
  schemas:
    ArrayOfInt:
      type: array
      items:
        type: integer
        format: int64
      example: [1, 2, 3]

components:
  schemas:
    ArrayOfUsers:
      type: array
      items:
        type: object
        properties:
          id:
            type: integer
          name:
            type: string
      example:
        - id: 10
          name: Jessica Smith
        - id: 20
          name: Ron Stewart



```

## Using $ref

```yaml=
components:
  schemas:
    User:
      properties:
        id:
          type: integer
        name:
          type: string
```

## Grouping Operations With Tags

```yaml=
paths:
  /pet/findByStatus:
    get:
      summary: Finds pets by Status
      tags:
        - pets
      ...
  /pet:
    post:
      summary: Adds a new pet to the store
      tags:
        - pets
      ...
  /store/inventory:
    get:
      summary: Returns pet inventories
      tags:
        - store
      ...
```


# 範例

- [openapi 2.0 可以用 edit 轉成 3.0](https://editor.swagger.io/?_ga=2.153179131.213900886.1632707085-1310170969.1632104466) 

###### tags: `2021`  `api` `design` `swagger` `api doc`
 

{%hackmd BJrTq20hE %}
