I have an OpenAPI schema that I generated using DRF-Spectacular. The part that matters is this:
...
patch:
operationId: patient_partial_update
parameters:
- in: path
name: patient_id
schema:
type: string
format: uuid
description: A UUID string identifying this patient.
required: true
tags:
- comp
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedPatientSerialiser'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedPatientSerialiser'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedPatientSerialiser'
...
components:
schemas:
ImageSerialiser:
type: object
properties:
image:
type: string
format: uri
alt:
type: string
maxLength: 150
session:
type: integer
maximum: 9223372036854775807
minimum: -9223372036854775808
format: int64
title: Session Number
angle:
allOf:
- $ref: '#/components/schemas/AngleEnum'
minimum: -9223372036854775808
maximum: 9223372036854775807
required:
- alt
- image
PatchedPatientSerialiser:
type: object
properties:
patient_no:
type: string
title: Patient Number
maxLength: 25
f_name:
type: string
nullable: true
title: First Name
maxLength: 100
l_name:
type: string
nullable: true
title: Last Name
maxLength: 100
sessions:
type: integer
maximum: 9223372036854775807
minimum: 0
format: int64
images:
type: array
items:
$ref: '#/components/schemas/ImageSerialiser'
...
As you can see, the PATCH request has a definition for multipart/form-data, however the client generated by openapi-generator-cli only includes handling for application/json input and passing FormData in results in an empty request. Obviously, passing it in as JSON doesn't work either because I'm working with file uploads, so I'm wondering if I've done something wrong or if I just have to write my own functions for this specific use case.
So I managed to find a workaround, but I'm still not sure if there's another way I should be doing it.
Firstly, I created a separate API endpoint for the Image instead of having nested data (probably a better way to do it anyway).
Secondly, I added COMPONENT_SPLIT_REQUEST=True
to my REST_FRAMEWORK
settings as per the drf-spectacular documentation. This separates create requests from retrieve requests and changes the image property to this as opposed to the uri format in the initial schema:
ImageSerialiserRequest:
type: object
properties:
image:
type: string
format: binary
This allows you to pass in the blob/file directly to the API and have it handled correctly.
Finally, I had to go into my schema file and manually remove the alternate requestBody
entries so my imageCreateRequest
looked like this:
post:
operationId: image_create
tags:
- comp
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/ImageSerialiserRequest'
This was the only way I could get the API client to generate properly and send data as FormData
. Even with the image being in binary format, it only generated 'application/JSON' methods. I'm not sure if this is an issue with the OpenAPI-generator or if there's some configuration options I've missed that could have fixed this for me, but it does seem weird that with all request types defined, it only generates for one regardless of the data types. I'm happy to hear if anyone else has found a different solution. For reference, I'm using the typescript-fetch
generator if that makes a difference.