Describing Request Body

정민교·2023년 7월 11일
0

📒Describing Request Body

request body는 보통 "create", "update"같은 operations(POST,PUT,PATCH)에 사용한다.

OpenAPI 3.0에서 requestBody 키워드로 request body를 정의할 수 있다.

✔️OpenAPI 2.0과 다른점

  • body와 form 파라미터는 requestBody로 대체된다.
  • operation들이 form data와 다른 media type들을 처리할 수 있다.
  • consumes 배열이 requestBody.content로 대체된다.
  • media type별려 schema를 다양화할 수 있다
  • Form data가 object를 포함할 수 있으며, 객체와 배열 직렬화 방법을 명시할 수 있다.
  • GET, DELETE, HEAD는 더 이상 request body를 허용하지 않는다. RFC 7231

✔️requestBody, content, and Media Types

OpenApi 3.0부터는 requestBody 키워드를 파라미터 payload와 구분하기 위해 사용한다.

requestBody에 여러 media type을 명시할 수 있고, 여러 media type에 서로 다른 스키마를 사용할 수 있다.

requestBodycontent 객체를 포함하고, 옵션으로 description(마크 다운 가능)과 required flag를 사용할 수 있다.

content는 operation에서 받을 수 있는 media type들을 리스트로 작성하고 각 media type에 사용할 schema를 명시한다.

request body는 모두 기본으로 optional이다. 따라서 request body가 반드시 필요하다면 required: true를 명시해야 한다.

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

content는 wildcard media type도 허용한다.

예를 들면 모든 이미지를 위한 image media type은 image/*,

모든 데이터를 위한 media type은 */*로 작성할 수 있으며, application/octet-stream과 기능적으로 동일하다.

paths:
  /avatar:
    put:
      summary: Upload an avatar
      requestBody:
        content:
          image/*:    # Can be image/png, image/svg, image/gif, etc.
            schema:
              type: string
              format: binary

✔️anyOf, oneOf

OpenAPI 3.0 은 anyOf, oneOf를 지원한다. request body에 대한 여러 스키마를 명시할 수 있다.

      requestBody:
        description: A JSON object containing pet information
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/Cat'
                - $ref: '#/components/schemas/Dog'
                - $ref: '#/components/schemas/Hamster'

✔️File Upload

✔️Request Body Examples

request body도 example이나 examples를 포함할 수 있다.

example, examplesrequestBody.content.<media-type>객체의 프로퍼티다. 이렇게 명시한 examplesschema에 작성한 examples를 override한다.

examplesummarydescription을 작성할 수 있다.

하나의 example을 위해서는 아래와 같이 작성한다.

      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
            example:
              name: Fluffy
              petType: dog

examples는 좀더 유연하게 inline example이 $ref로 참조하거나, example payload를 포함하고 있는 외부 URL을 명시할 수도 있다.

      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
            examples:
              dog:  # <--- example name
                summary: An example of a dog
                value:
                  # vv Actual payload goes here vv
                  name: Fluffy
                  petType: dog
              cat:  # <--- example name
                summary: An example of a cat
                externalValue: http://api.example.com/examples/cat.json   # cat.json contains {"name": "Tiger", "petType": "cat"}
              hamster:  # <--- example name
                $ref: '#/components/examples/hamster'
components:
  examples:
    hamster:  # <--- example name
      summary: An example of a hamster
      value:
        # vv Actual payload goes here vv
        name: Ginger
        petType: hamster

✔️Reusable Bodies

request body를 global components.requestBodies 섹션에 정의하고 $ref로 참조할 수 있도록 할 수 있다.

paths:
  /pets:
    post:
      summary: Add a new pet
      requestBody:
        $ref: '#/components/requestBodies/PetBody'
  /pets/{petId}
    put:
      summary: Update a pet
      parameters: [ ... ]
      requestBody:
        $ref: '#/components/requestBodies/PetBody'
components:
  requestBodies:
    PetBody:
      description: A JSON object containing pet information
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Pet'

✔️Form Data

"form data"라는 용어는 application/x-www-form-urlencodedmultipart/form-data media type에 사용된다. 보통 HTML forms를 통해 전송되는 데이터다.

  • application/x-www-form-urlencoded는 ASCII 문자열 데이터로 전송된다. key=value 형태로 쿼리 파라미터와 비슷하다.
  • multipart/form-data는 binary data 전송을 허용하고, single message에 여러 media type을 사용해서 전송하는 것도 허용한다.
    form의 각 필드는 HTTP headers payload에 자신만의 section을 가진다. multipart request는 보통 file uploads에 사용된다.

예를 들어 HTML POST form이 다음과 같다고 가정한다.

<form action="http://example.com/survey" method="post">
  <input type="text"   name="name" />
  <input type="number" name="fav_number" />
  <input type="submit"/>
</form>

전송 시 form POSTs data가 form 전송 요청의 endpoint로 전송된다.

POST /survey HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
name=Amy+Smith&fav_number=42

OpenAPI 3.0에서 form data는 type: object schema를 사용해서 모델링한다.

schema는 html form field의 이름을 object의 프로퍼티로 가진다.

paths:
  /survey:
    post:
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                name:          # <!--- form field name
                  type: string
                fav_number:    # <!--- form field name
                  type: integer
              required:
                - name
                - email

Form fields는 원시값, 배열, 객체를 포함할 수 있다.

배열은 기본적으로 array_name=value1&array_name=value2로,

객체는 기본적으로 prop1=value1&prop2=value2로 직렬화된다.

하지만 OpenAPI 3.0 명세서에 정의된 다른 직렬화 전력을 사용해도 된다.

Serialization strategy는 encoding 섹션에 명시한다.

      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                color:
                  type: array
                  items:
                    type: string
            encoding:
              color:            # color=red,green,blue
                style: form
                explode: false

기본적으로 reversed characters(:/?#[]@!$&'()*+,;=)가 form field 값으로 사용되면(application/x-www-form-urlencoded 바디에 사용되면) percent-encoded되어 전송된다.

reversed characters가 그대로 전송되도록 허용하려면 allowReversed 키워드를 사용한다.

      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                foo:
                  type: string
                bar:
                  type: string
                baz:
                  type: string
            encoding:
              # Don't percent-encode reserved characters in the values of "bar" and "baz" fields
              bar:
                allowReserved: true
              baz:
                allowReserved: true

✔️Complex Serialization in Form Data

직렬화 전략은 styleexplode키워드에 의해 결정된다.

복잡한 시나리오로 JSON 중첩 배열이 form data에 있는 경우 등이 있다. 이런 경우 contentType 키워드에 media type을 명시해서 complex field 값들을 인코딩한다.

메시지는 JSON으로 바로 올 수도 있고,

JSON 데이터 안에 다음과 같은 form field named payload가 있을 수도 있다(URL-encoding 적용 전).

payload={"text":"Swagger is awesome"}

이런 경우 다음과 같이 작성할 수 있다.

openapi: 3.0.0
info:
  version: 1.0.0
  title: Slack Incoming Webhook
externalDocs:
  url: https://api.slack.com/incoming-webhooks
servers:
  - url: https://hooks.slack.com
paths:
  /services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX:
    post:
      summary: Post a message to Slack
      requestBody:
        content:
        
          application/json:
            schema:
              $ref: '#/components/schemas/Message'
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                payload:     # <--- form field that contains the JSON message
                  $ref: '#/components/schemas/Message'
            encoding:
              payload:
                contentType: application/json
      responses:
        '200':
          description: OK
components:
  schemas:
    Message:
      title: A Slack message
      type: object
      properties:
        text:
          type: string
          description: Message text
      required:
        - text
profile
백엔드 개발자

0개의 댓글