swagger-api / swagger-js

Javascript library to connect to swagger-enabled APIs via browser or nodejs
http://swagger.io
Apache License 2.0
2.62k stars 761 forks source link

Sending path parameters and formData #1429

Open enricogigantiello opened 5 years ago

enricogigantiello commented 5 years ago

Q&A

Content & configuration

Swagger/OpenAPI definition:

{
  "swagger":"2.0",
  "info":{
    "title":"API V1",
    "version":"v1"
  },
  "paths":{
    "/items":{
      "post":{
        "summary":"Creates an item",
        "tags":[
          "Items"
        ],
        "consumes":[
          "application/json",
          "application/xml"
        ],
        "operationId":"createItem",
        "parameters":[
          {
            "name":"access-token",
            "in":"header",
            "type":"string"
          },
          {
            "name":"client",
            "in":"header",
            "type":"string"
          },
          {
            "name":"expiry",
            "in":"header",
            "type":"string"
          },
          {
            "name":"token-type",
            "in":"header",
            "type":"string"
          },
          {
            "name":"uid",
            "in":"header",
            "type":"string"
          },
          {
            "name":"item",
            "in":"body",
            "schema":{
              "type":"object",
              "properties":{
                "name":{
                  "type":"string"
                },
                "description":{
                  "type":"string"
                },
                "user_id":{
                  "type":"integer"
                }
              },
              "required":[
                "name",
                "user_id"
              ]
            }
          }
        ],
        "responses":{
          "200":{
            "description":"item created",
            "schema":{
              "type":"object",
              "properties":{
                "id":{
                  "type":"integer"
                },
                "name":{
                  "type":"string"
                },
                "description":{
                  "type":"string"
                },
                "user_id":{
                  "type":"integer"
                },
                "created_at":{
                  "type":"string"
                },
                "updated_at":{
                  "type":"string"
                }
              },
              "required":[
                "id"
              ]
            }
          },
          "422":{
            "description":"invalid request"
          }
        }
      },
      "get":{
        "summary":"Lists items",
        "tags":[
          "Items"
        ],
        "description":"Lists items",
        "produces":[
          "application/json"
        ],
        "operationId":"getItems",
        "responses":{
          "200":{
            "description":"success"
          },
          "422":{
            "description":"invalid request"
          }
        }
      }
    },
    "/items/{id}":{
      "get":{
        "summary":"Retrieves an item",
        "tags":[
          "Items"
        ],
        "produces":[
          "application/json",
          "application/xml"
        ],
        "parameters":[
          {
            "name":"id",
            "in":"path",
            "type":"string",
            "required":true
          }
        ],
        "operationId":"showItem",
        "responses":{
          "200":{
            "description":"item found",
            "schema":{
              "type":"object",
              "properties":{
                "id":{
                  "type":"integer"
                },
                "name":{
                  "type":"string"
                },
                "description":{
                  "type":"string"
                },
                "user_id":{
                  "type":"integer"
                },
                "created_at":{
                  "type":"string"
                },
                "updated_at":{
                  "type":"string"
                }
              },
              "required":[
                "id"
              ]
            }
          },
          "404":{
            "description":"item not found"
          }
        }
      },
      "put":{
        "summary":"Updates an item",
        "tags":[
          "Items"
        ],
        "produces":[
          "application/json",
          "application/xml"
        ],
        "operationId":"updateItem",
        "parameters":[
          {
            "name":"access-token",
            "in":"header",
            "type":"string"
          },
          {
            "name":"client",
            "in":"header",
            "type":"string"
          },
          {
            "name":"expiry",
            "in":"header",
            "type":"string"
          },
          {
            "name":"token-type",
            "in":"header",
            "type":"string"
          },
          {
            "name":"uid",
            "in":"header",
            "type":"string"
          },
          {
            "name":"id",
            "in":"path",
            "type":"string",
            "required":true
          },
          {
            "name":"item",
            "in":"body",
            "schema":{
              "type":"object",
              "properties":{
                "name":{
                  "type":"string"
                },
                "description":{
                  "type":"string"
                },
                "user_id":{
                  "type":"integer"
                }
              },
              "required":[
                "name",
                "id"
              ]
            }
          }
        ],
        "responses":{
          "200":{
            "description":"item updated",
            "schema":{
              "type":"object",
              "properties":{
                "id":{
                  "type":"integer"
                },
                "name":{
                  "type":"string"
                },
                "description":{
                  "type":"string"
                },
                "user_id":{
                  "type":"integer"
                },
                "created_at":{
                  "type":"string"
                },
                "updated_at":{
                  "type":"string"
                }
              },
              "required":[
                "id"
              ]
            }
          },
          "404":{
            "description":"item not found"
          }
        }
      },
      "delete":{
        "summary":"Delete an item",
        "tags":[
          "Items"
        ],
        "consumes":[
          "application/json"
        ],
        "produces":[
          "application/json"
        ],
        "operationId":"deleteItem",
        "parameters":[
          {
            "name":"access-token",
            "in":"header",
            "type":"string"
          },
          {
            "name":"client",
            "in":"header",
            "type":"string"
          },
          {
            "name":"expiry",
            "in":"header",
            "type":"string"
          },
          {
            "name":"token-type",
            "in":"header",
            "type":"string"
          },
          {
            "name":"uid",
            "in":"header",
            "type":"string"
          },
          {
            "name":"id",
            "in":"path",
            "type":"string",
            "required":true
          }
        ],
        "responses":{
          "200":{
            "description":"Destroy the item"
          },
          "404":{
            "description":"item not found"
          }
        }
      }
    },
    "/items/{id}/upload":{
      "put":{
        "summary":"Uploads files to an item",
        "tags":[
          "Items"
        ],
        "produces":[
          "application/json",
          "application/xml"
        ],
        "consumes":[
          "multipart/form-data"
        ],
        "operationId":"uploadItem",
        "parameters":[
          {
            "name":"access-token",
            "in":"header",
            "type":"string"
          },
          {
            "name":"client",
            "in":"header",
            "type":"string"
          },
          {
            "name":"expiry",
            "in":"header",
            "type":"string"
          },
          {
            "name":"token-type",
            "in":"header",
            "type":"string"
          },
          {
            "name":"uid",
            "in":"header",
            "type":"string"
          },
          {
            "name":"id",
            "in":"path",
            "type":"integer",
            "required":true
          },
          {
            "name":"item[picture]",
            "in":"formData",
            "type":"file",
            "description":"The file to upload."
          }
        ],
        "responses":{
          "200":{
            "description":"item picture uploaded",
            "schema":{
              "type":"object",
              "properties":{
                "id":{
                  "type":"integer"
                },
                "name":{
                  "type":"string"
                },
                "description":{
                  "type":"string"
                },
                "image":{
                  "type":"string"
                },
                "user_id":{
                  "type":"integer"
                },
                "created_at":{
                  "type":"string"
                },
                "updated_at":{
                  "type":"string"
                }
              },
              "required":[
                "id"
              ]
            }
          },
          "404":{
            "description":"item not found"
          }
        }
      }
    },
    "/auth":{
      "post":{
        "summary":"Creates a user",
        "tags":[
          "Users"
        ],
        "consumes":[
          "application/json",
          "application/xml"
        ],
        "parameters":[
          {
            "name":"registration",
            "in":"body",
            "schema":{
              "type":"object",
              "properties":{
                "email":{
                  "type":"string"
                },
                "password":{
                  "type":"string"
                },
                "password_confirmation":{
                  "type":"string"
                }
              }
            }
          }
        ],
        "responses":{
          "201":{
            "description":"user created"
          },
          "422":{
            "description":"invalid request"
          }
        }
      }
    },
    "/auth/sign_in":{
      "post":{
        "summary":"Logs in a user",
        "tags":[
          "Users"
        ],
        "consumes":[
          "application/json",
          "application/xml"
        ],
        "parameters":[
          {
            "name":"registration",
            "in":"body",
            "schema":{
              "type":"object",
              "properties":{
                "email":{
                  "type":"string"
                },
                "password":{
                  "type":"string"
                }
              }
            }
          }
        ],
        "responses":{
          "201":{
            "description":"user logged in"
          },
          "422":{
            "description":"invalid request"
          }
        }
      }
    }
  }
}

Swagger-Client usage:

import Swagger from 'swagger-client';
const SwaggerApiRequest = Swagger({ url: `${API_URL}/api-docs/v1/swagger.json` });
const applyHeaders = (headers) => (req) => {
  if(headers){
    Object.keys(headers).map(headerKey => 
      req.headers[headerKey] = headers[headerKey]
    )
  }
  return req;
}

function createItem(values) {
  let headers = {'Content-Type': 'multipart/form-data', 'access-token': xxxx, 'client': yyy, 'token-type': "Bearer"}
  let uploadBody = new FormData();
  uploadBody.append("picture", values.picture[0], values.picture[0].name);
  SwaggerApiRequest.client.apis.Items.uploadItem({id: values.id, body: uploadBody}, {requestInterceptor: applyHeaders(headers)})
      .then(res => {
        console.log('result', res)
      })
      .catch(err => {
        console.log('ERROR', err);       
      })
}

How can we help?

Hi all, having big issues in finding any documentation on this. There is a related issue but its from long ago and doesnt give any useful explanation on how it was solved.

I have a rails api exposing a PUT item/:id/upload endpoint to upload a file for an item. In order to upload a file, im creating a FormData object in js and want to send this object along with the 'id' needed as path parameter to reference the correct endpoint.

So while this works fine in my swagger-ui in rails (I just have two inputs, type number in path and type file in formdata) I couldnt find any way to trigger a request using the tags interface of swagger-js which would send both the id and the formdata object. Referring to the sample above these are all ways I tried which didnt succeed:

SwaggerApiRequest.client.apis.Items.uploadItem({id: values.id, body: uploadBody}, {requestInterceptor: applyHeaders(headers)})
SwaggerApiRequest.client.apis.Items.uploadItem({id: values.id, formData: uploadBody}, {requestInterceptor: applyHeaders(headers)})
SwaggerApiRequest.client.apis.Items.uploadItem({id: values.id, 'form-data': uploadBody}, {requestInterceptor: applyHeaders(headers)})

It does send the formdata If I just pass that as first argument to the function like this:

SwaggerApiRequest.client.apis.Items.uploadItem(uploadBody, {requestInterceptor: applyHeaders(headers)})

but then it would lament missing an id in the path. Also tried appending id inside the formdata object and didnt work.

If the sample above is not clear enough, I found a very similar use case in the test pet sample in this repository: https://github.com/swagger-api/swagger-js/blob/master/test/data/petstore.json#L376

my question essentially is, how would you use the '/pet/{petId}/uploadImage' endpoint through swagger-js's tags interface?

Thanks :-)

darbyo commented 5 years ago

Hey @enricogigantiello , did you ever get an answer to this? I'm having the same problem and struggling to find a solution!