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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for JSON objects for the non-file fields #278

Closed
2 tasks done
radomird opened this issue Oct 1, 2021 · 8 comments 路 Fixed by #288
Closed
2 tasks done

Add support for JSON objects for the non-file fields #278

radomird opened this issue Oct 1, 2021 · 8 comments 路 Fixed by #288

Comments

@radomird
Copy link
Contributor

radomird commented Oct 1, 2021

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the feature has not already been requested

馃殌 Feature Proposal

Currently the plugin doesn't support complex JSON objects as non-file field values. It could be an interesting addition to the plugin.

Motivation

A user opened an issue where he is trying to send a JSON object through and then expects that to be validated.
Link to the issue is here: fastify/help#525 (comment)

Example

Below there's the code for both the server and the client (the non-file field in question is the metadata field).

server:

const util = require("util");
const { pipeline } = require("stream");
const pump = util.promisify(pipeline);
const fs = require("fs");

const fastify = require("fastify")({
  logger: true,
  ajv: {
    customOptions: {
      coerceTypes: false,
      removeAdditional: false,
    },
  },
});

(async () => {
  const onFile = async (part) => {
    await pump(part.file, fs.createWriteStream(part.filename));
  };

  fastify.register(require("fastify-multipart"), {
    attachFieldsToBody: true,
    onFile,
  });

  fastify.post(
    "/upload/files",
    {
      schema: {
        body: {
          type: "object",
          required: ["metadata"],
          properties: {
            metadata: {
              type: "object",
              required: ["amount", "kind", "color"],
              properties: {
                amount: {
                  type: "string",
                },
                kind: {
                  type: "string",
                },
                color: {
                  type: "object",
                  required: ["main"],
                  properties: {
                    main: {
                      type: "string",
                    },
                    secondary: {
                      type: "string",
                    },
                  },
                },
              },
            },
          },
        },
      },
    },
    async function (req, reply) {
      reply.send("ok");
    }
  );

  fastify.listen(3000, (err, address) => {
    if (err) throw err;
    console.info(`listening on port ${address}`);
  });
})();

client:

const axios = require("axios");
const FormData = require("form-data");
const fs = require("fs");

const payload = {
  amount: "amount",
  kind: "kind",
  color: { main: "yellow", secondary: "green" },
};

const data = new FormData();
data.append("metadata", JSON.stringify(payload));

const config = {
  method: "post",
  url: "http://localhost:3000/upload/files",
  headers: {
    ...data.getHeaders(),
  },
  data: data,
  maxContentLength: Infinity,
  maxBodyLength: Infinity,
};

axios(config)
  .then(function (response) {
    console.log(JSON.stringify(response.data));
  })
  .catch(function (error) {
    console.log(error);
  });
@ShogunPanda
Copy link
Contributor

I've implemented in #288

Note that in order to be parsed, the content type must be specified:

data.append("metadata", JSON.stringify(payload), {contentType: 'application/json'});

@Eomm Eomm closed this as completed in #288 Nov 1, 2021
@meotimdihia
Copy link

meotimdihia commented Jan 15, 2022

@ShogunPanda I have got this error when using it with typescript:

            formData.append("metadata", JSON.stringify(data[key][i]), {
              contentType: "application/json"
            })

Code_2022-01-16_00-25-56

even when I tried to ignore the error. I still get the error when submitting form:

TypeError: Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'.

@ShogunPanda
Copy link
Contributor

It seems to come from form-data and not from our package.

I'm not at PC at the moment, but out of my mind I would try with content-type. Otherwise double check form-data's types.

Let me know if it solves, otherwise on Mon I'll take a second look.

@meotimdihia
Copy link

meotimdihia commented Jan 16, 2022

@ShogunPanda https://developer.mozilla.org/en-US/docs/Web/API/FormData/append
FormData.append doesn't have the format like your example.

@ShogunPanda
Copy link
Contributor

@meotimdihia Node does not ship FormData, and I think in you case it comes from https://www.npmjs.com/package/form-data.
This package might have a different API and types and you should double check there.

@meotimdihia
Copy link

@ShogunPanda the pack form-data was failed with the code:

         formData.append("metadata", JSON.stringify(data[key][i]), {
              contentType: "application/json"
            })

TypeError: Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'.

And do we have a way to post JSON objects from the browser?

@ShogunPanda
Copy link
Contributor

I'm sorry, but this is not related to fastify/fastify-multipart at all.

I have no idea on your client setup so I can't help.

@climba03003
Copy link
Member

climba03003 commented Jan 20, 2022

@ShogunPanda the pack form-data was failed with the code:

         formData.append("metadata", JSON.stringify(data[key][i]), {
              contentType: "application/json"
            })

TypeError: Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'.

And do we have a way to post JSON objects from the browser?

I would recommend you open an issue on form-data (if you are using the npmjs one) instead of asking in a closed issue.
It is totally unrelated to fastify-multipart.

If you are using the browser default FormData. Please check the below link for how to specify content-type.
https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects

@fastify fastify locked as resolved and limited conversation to collaborators Jan 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants