tsoa-swagger: file parameter is always undefined in upload - node.js

I have a problem with Tsoa nodejs File upload
I wrote the method based on the tsoa documentation but the output varible is always undefined
This is my method
#Post('/uploadNewExporterTemplate')
public async uploadNewExporterTemplate(
#Query() templateName: string,
#Query() unit: string,
#Query() testWith: string,
#UploadedFile() file: Express.Multer.File,
) {
const mul = multer()
console.log(file,unit,testWith);
return {stat:"Ok",ss:templateName}
}
And this is the swagger result
and finally this the debug result

I'm not sure why but according to provided screenshot of Swagger UI, your file field is in Request body section, but the rest of the fields are in Parameters section. As far as I know, all fields should be in one section called Request body or Parameters.
I suggest you try changing Query() to FormField() accordingly to tsoa docs.
If above does not help, I have a few suggestions:
Check what's inside generated routes file. There should be some multer logic added by tsoa.
Compare your generated swagger.json with the one provided in the Swagger example.
Try running the request outside Swagger UI (e.g.: Postman) or use DevTools to check what is Swagger UI does under the hood (Network tab, check the requests).

Related

Body is not getting parsed in GET method

I am using mockoon for API simulation. I created 2 routes there with method GET and its body contains(responds with) JSON object. I noticed that my express app is not able to parse one of the routes. But the route that has JSON object in body which contains ARRAY is getting parsed. I tested both routes with Express(by console.log) and in chrome browser(I have JSON formatter extension) and it is behaving the same meaning response that does not contain ARRAY is not getting parsed but the response with array is getting parsed(behaving normally). Let me show the screenshots:
Express(by console.log):
With array:
Without array:
Chrome(JSON Formatter extension):
With array(extension is able to parse):
Without array(extension is not able to parse):
I tried adding Header(Content-Type: application/json) to the route in mockoon. But still, I am not aware of what is going on here. Someone please explain
The express code:
const iabs_client = await axios.get(
"http://localhost:3001/iabs-client
);
Here is the route created in Mockoon(without array inside JSON):
P.S mockoon is a program that creates endpoints in localhost, useful for API simulation when developing front-end without having backend yet
The trailing comma after "something" is not valid JSON. Edit your Mockoon body to remove the comma and it should work.

How supply default values in calling a remote endpoint

I am an amateur programmer and cannot figure this out based on the documentation and examples provided.
Based on their sample capsule on https://bixbydevelopers.com/dev/docs/sample-capsules/samples/http, they directly called
var response = http.getUrl(config.get('remote.url') + '/shoes', options);
They do have documentation on what http.getUrl parameters are but no examples on how it should be formatted syntax-wise.
I also don't know what would be the point of creating an endpoints.bxb for API calls file if they don't use it and just call it manually in the .js file.
Any help is greatly appreciated!
The base method signature for http.getUrl is http.getUrl(url, options) where the url variable is a String and the options variable is a JSON object containing any or all of the following keys:
format: Output format.
query: Object containing unencoded keys and values for URL query string.
cacheTime: Cache time in milliseconds.
basicAuth: Basic Authentication; value must be an object with username and password.
You can learn more by exploring the documentation's http section here.
Regarding the http sample you referenced: It shows multiple ways to reach the same outcome. The endpoints.bxb file has the two following action-endpoints:
A local endpoint where the GET is handled by the Javascript file:
action-endpoint (FindShoe) {
accepted-inputs ()
local-endpoint (FindShoe.js)
}
A remote endpoint where the GET is defined within the endopoints.bxb file itself and doesn't require a Javascript file.
action-endpoint (FindShoeRemoteEndpoint) {
accepted-inputs ()
remote-endpoint ("{remote.url}/shoes") {
method (GET)
}
}

Verify Joi validation was added to hapi route

I am reusing a Joi schema in multiple places in my code and I would like to find a clean way to test that my endpoints are assigned the validation schema. This would be helpful since I could verify the schema behaved the way I expect without having to repeat the same series of tests everywhere the schema is used.
If I have a hapi server route:
server.route({
method: POST,
path: 'myUrl',
config: {
validate: {
payload: validation.myJoiValidation,
}
}
})
how would I test that the validation.myJoiValidation object has been assigned to the config.validate.payload element?
I dug down into the hapi request object and found that what I am looking for is located in the request.route.settings.validate.payload._inner.children object, but I really don't want to have to rely on that for what I am trying to do.
If you have a server running in the context of your test, you can get the validation schema being used with:
const schema = server.match('post', 'myUrl').settings.validate.payload;
Schemas can't be directly compared (as with Hoek.deepEqual), but they can be compared by using joi.describe, so:
expect(joi.describe(schema)).to.equal(joi.describe(validation.myValidation));
Or, if you are using mocha/chai I think this would be:
expect(joi.describe(schema)).to.deep.equal(joi.describe(validation.myValidation));
In your unit tests make a request with request or similar package with a payload that doesn't pass the validation. Ensure the response code is a 400.
Example test from a project of mine. It tests a regex Join validation on this route. This uses a small promise wrapper around request called yarp.

Podio file attached to item cannot be downloaded

I have an issue trying to download files attached to Podio items:
podio.request('get', '/file/{file_id}/raw').then(console.log);
The above program displays:
{}
This is a JSON stringified empty object (instead of raw file content).
Details:
The above file can be accessed with its URL when logged in
The above code is run after proper authentication
It actually works when using a file_id from an image field of the item, but not from a file attachment (pdf files in my case).
When using API endpoint /item/app/{app_id}/filter to get a list of items, the property file_count is set, but not files. I have to request /item/{item_id} individually to get the files property included in the response, not sure why.
Question: Do you know what is the issue, and how I can download raw attached files?
EDIT: aditionnal info
If I request a single file metadata using the folowing command:
podio.request('get', '/file/1234').then(console.log);
I get a file JSON object which includes many fields, but not the file content :
{
...
link: 'https://files.podio.com/1234',
file_id: 1234,
...
}
As stated in my comment to #stengaard, if I try to request the API for the above link, here is the response :
{ [PodioNotFoundError: [object Object]]
message:
{ error_parameters: {},
error_detail: null,
error_propagate: false,
request:
{ url: 'http://api.podio.com/1234',
query_string: '',
method: 'GET' },
error_description: 'No matching operation could be found. The path \'/1234\' was not found..',
error: 'not_found' },
status: 404,
url: 'https://api.podio.com:443/1234',
name: 'PodioNotFoundError' }
To use the GET /file/{file_id}/raw endpoint you need an API key with elevated trust levels.
Instead use GET /file/{file_id} endpoint. That contains a link attribute (a URL) you should follow to get the file content.
The link attribute will look like: https://files.podio.com/{file_id}. To fetch the file do https://files.podio.com/{file_id}?oauth_token={oauth_token}. Where the OAuth token is the same as the one used to GET /file/{file_id}. If you know the file ID (e.g. from a GET /item/{item_id} you can skip the GET /file/{file_id} and contact files.podio.com directly. (Note: You can also set the Authorization: OAuth2 {oauth_token} header in your HTTP request if you don't like passing the auth token in a URL paramter.)
For an example on how to use it see https://github.com/podio/podio-js/blob/master/lib/general.js#L11
Typically in the JS client, if you use podio as your Podio API object, the OAuth token would be located there:
podio.authObject.accessToken
So to get the raw content of the file in nodejs:
var url = 'https://files.podio.com/'+file_id+'?oauth_token='+podio.authObject.accessToken;
request(url, function (err, fileContent) {
// use fileContent here, write to a file, etc...
});
It seems your request has an error.
please try the below method and get raw file content from its response.
podio.request('get', '/file/{file_id}').then(console.log);
FYI, we couldn't get the files by filtering the items. we need to request /item/{item_id} individually to get the files property as you said.

Not found route not found in Sailsjs

Based on Sailsjs documentation, it is possible to add on the routes file a response with a syntax like this:
module.exports.routes = {
'/foo': {response: 'notFound'}
};
This searches for the notFound.js file in the /response directory, which I've in there.
So in my routes.js file I've added this as the end of the other routes in order to catch the not found routes, it is something like this:
module.exports.routes = {
'get /myroute/:myPara/': 'MyController.getAll',
'get /myroute/:myPara/': 'MyController.getOne',
'post /myroute/:myPara/': 'MyController.create',
'/*' : {response: 'notFound'}
};
I've realized that never finds the last route, I've also tried removing the slash ( doing '*' ), but nothing works.
Am I missing something? Thanks!
Sails already take care of the 404 notFound : here
Sails call res.notFound() and you can override the default notFound():
res.notFound() (like other userland response methods) can be overridden or modified. It runs the response method defined in /responses/notFound.js, which is bundled automatically in newly generated Sails apps. If a notFound.js response method does not exist in your app, Sails will implicitly use the default behavior.

Resources