openapi-python-client icon indicating copy to clipboard operation
openapi-python-client copied to clipboard

Add support for content type application/merge-patch+json

Open raman-nbg opened this issue 5 years ago • 2 comments

Describe the bug In my Open API Spec I have a PATCH method, that defines a request body (content-type=merge-patch+json). The generated code/method, does not contain a argument for the request body. Therefore I can't send a valid request with the generated code.

To Reproduce Steps to reproduce the behavior:

Use the following snippet from a open api spec (version 3):

  /resource/{resourceId}:
    patch:
      summary: Partial update an existing resource
      operationId: partialUpdate
      tags:
      - resources
      parameters:
        - name: resourceId
          in: path
          required: true
          description: The id of the resource that should be updated
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/merge-patch+json:
            schema:
              $ref: "#/components/schemas/Resource"
      responses:
        '204':
          description: The update was successful
        '500':
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

Generate your code as usual.

The generated code looks like the following one:

def partial_update(*, client: Client, resource_id: str, ) -> Union[None, Error]:

    url = "{}/resources/{resourceId}".format(
        client.base_url, experimentId=experiment_id
    )

    headers: Dict[str, Any] = client.get_headers()

    response = httpx.patch(url=url, headers=headers)

    if response.status_code == 204:
        return None
    if response.status_code == 500:
        return Error.from_dict(cast(Dict[str, Any], response.json()))
    else:
        raise ApiResponseError(response=response)

Expected behavior The generated code should contain a argument for the body.

OpenAPI Spec File See above

Desktop (please complete the following information):

  • OS: macOS 10.15.6
  • Python Version: 3.8.5
  • openapi-python-client version: 0.5.5

raman-nbg avatar Sep 16 '20 11:09 raman-nbg

I've never used the content-type application/merge-patch+json. Can you provide an example of how you'd like to see the request built with httpx? If it were application/json, it would do something like:

response = httpx.patch(url=url, headers=headers, json=dict_of_data_here)

Does simply setting the content-type header manually let us use the same method for merge-patch+json? Or do we need something like httpx.patch(url=url, headers=headers, data=json.dumps(dict_of_data_here))

dbanty avatar Sep 16 '20 13:09 dbanty

The request would be the same as with application/json. Just the content-type is different.

Here you find an article about application/merge-patch+json (implemented with Spring Boot): https://cassiomolin.com/2019/06/10/using-http-patch-in-spring/

JSON Patch Merge is specified in RFC 7396.

The main goal of JSON Patch Merge is, that only a partial update should be performed. In a normal/usual PUT request the server can not determin if a property should not be changed or should be changed to null.

PUT https://.../resources/1
content-type: application/json

{
  "prop1":"newValue",
  "prop2":null
}

Now it is not clear if prop2 should be changed to null or it should not be changed.

Vise-versa the client must always send the full resource with all properties, even if only one property changes.

Therefore a Patch Merge is very usefull to save both, bandwith and also server resources (CPU time).

raman-nbg avatar Sep 16 '20 13:09 raman-nbg

Pretty sure this works as of 0.12.3

dbanty avatar Aug 13 '23 02:08 dbanty