Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing "encoding" field #1087

Open
1 of 3 tasks
JMLX42 opened this issue Oct 4, 2024 · 2 comments
Open
1 of 3 tasks

Missing "encoding" field #1087

JMLX42 opened this issue Oct 4, 2024 · 2 comments

Comments

@JMLX42
Copy link
Contributor

JMLX42 commented Oct 4, 2024

Hello,

I want to make sure the Swagger UI file dialog will limit the selectable file(s) to a specific extension (in this case .glb).
Based on my discussion with ChatGPT and my read of the OAS spec, it should be done using the encoding object.

How to reproduce

#[derive(ToSchema, MultipartForm)]
pub(crate) struct GlbFileUpload {
    /// The binary glTF (`.glb`) file to import.
    #[schema(format = Binary, encoding = "model/gltf-binary", value_type=Vec<u8>)]
    file: TempFile,
}

/// Import a glTF file
///
/// Imports a glTF file from a multipart form data.
/// This endpoint accepts a `.glb` file and supports additional query parameters.
#[utoipa::path(
    tag = "glTF",
    params(
        GltfResourceQueryParameters,
    ),
    request_body(content = inline(GlbFileUpload), content_type = "multipart/form-data"),
    responses(GltfResourceResponse),
)]
#[post("/gltf/import")]
pub async fn import_gltf_file(
    req: HttpRequest,
    db: web::Data<Database>,
    query: web::Query<GltfResourceQueryParameters>,
    MultipartForm(payload): MultipartForm<GlbFileUpload>,
) -> Result<HttpResponse<actix_web::body::BoxBody>, ErrorList> {
    info!(
        "received `{}` ({} bytes) for import",
        payload.file.file_name.unwrap(),
        payload.file.size
    );

    let file = Arc::new(payload.file.file);
    let db = db.into_inner();

    Ok(
        ResponseBuilder::<GltfResourceObject>::new(req.uri().clone())
            .relationship_resolver(AssetResolver::new(db.clone()))
            .relationship_resolver(SceneResolver::new(db.clone()))
            .query_parameters(query.into_inner())
            .data(Box::new(move || {
                let db = db.clone();
                let file = file.clone();

                Box::pin(async move {
                    gltf_live_importer::import_from_reader(file.as_ref(), &db)
                        .await
                        .map(|r| r.into_resource_object())
                })
            }))
            .build()
            .await
            .into(),
    )
}

OAS Spec

In the OpenAPI Specification (OAS) 3.0, the encoding field is used to describe how a specific property of a multipart/form-data request body is encoded. Specifically, it is used for properties that are defined as file uploads. Here is the relevant section from the OpenAPI Specification (3.0.3):
Encoding Object Definition (OAS 3.0.3)

The encoding object is defined as follows:

encoding: Map[string, Encoding Object
A map allowing additional information to be provided as headers, for example Content-Disposition. encoding is only > applicable to multipart and application/x-www-form-urlencoded request bodies.

Within the encoding object, you can use the contentType field to specify the MIME type for a particular property:

paths:
  /upload:
    post:
      summary: Upload a glTF .glb file
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                  description: The glTF .glb file to upload
                  example: "file.glb"
            encoding:
              file:
                contentType: model/gltf-binary
      responses:
        '200':
          description: Successful upload
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

The key fields related to file uploads are:

  • contentType (string): The Content-Type for encoding a specific property. This can be used to describe the media type for file uploads, such as model/gltf-binary for .glb files.
    - Example from OAS 3.0.3:
    - When this is a multipart content-type, this property is used to describe the media type of a file part.

https://spec.openapis.org/oas/v3.0.3#encoding-object

To Do

  • Validate that this field is indeed missing
  • Design an implementation
  • Implement the validated design
@juhaku
Copy link
Owner

juhaku commented Oct 4, 2024

Yup, that is surely missing from the macro syntax as discussed here #811 (comment) #1055.

@juhaku
Copy link
Owner

juhaku commented Oct 23, 2024

I think we can verify that the the field is actually missing, from the generation side. I'll mark it as checked for the above todo list.

jsoo1 added a commit to jsoo1/utoipa that referenced this issue Dec 13, 2024
Though only in a limited fashion - notable fields are still not
implemented.

Though this does let you do:

```rs
   request_body(
       content(...)
       encoding(
           ("field_name", (
               content_type = "application/json",
               explode = true,
               allow_reserved = true,
           ))
       )
   )
```

Partially addresses juhaku#1087
jsoo1 added a commit to jsoo1/utoipa that referenced this issue Dec 13, 2024
Though only in a limited fashion - notable fields are still not
implemented.

Though this does let you do:

```rs
   request_body(
       content(...)
       encoding(
           ("field_name", (
               content_type = "application/json",
               explode = true,
               allow_reserved = true,
           ))
       )
   )
```

Partially addresses juhaku#1087
jsoo1 added a commit to jsoo1/utoipa that referenced this issue Dec 17, 2024
Though only in a limited fashion - notable fields are still not
implemented.

Though this does let you do:

```rs
   request_body(
       content(...)
       encoding(
           ("field_name", (
               content_type = "application/json",
               explode = true,
               allow_reserved = true,
           ))
       )
   )
```

Partially addresses juhaku#1087
jsoo1 added a commit to jsoo1/utoipa that referenced this issue Dec 17, 2024
Though only in a limited fashion - notable fields are still not
implemented.

Though this does let you do:

```rs
   request_body(
       content(...)
       encoding(
           ("field_name", (
               content_type = "application/json",
               explode = true,
               allow_reserved = true,
           ))
       )
   )
```

Partially addresses juhaku#1087
juhaku pushed a commit to jsoo1/utoipa that referenced this issue Dec 18, 2024
Though only in a limited fashion - notable fields are still not
implemented.

Though this does let you do:

```rs
   request_body(
       content(...)
       encoding(
           ("field_name", (
               content_type = "application/json",
               explode = true,
               allow_reserved = true,
           ))
       )
   )
```

Partially addresses juhaku#1087
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants