Swagger Nest.js ValidationPipe ApiBadRequestResponse - node.js

👋I just started playing around with Swagger and everything is amazing. I was able to document all API in an hour or so but I got stuck solving one last issue.
How can I tell swagger to show ApiBadRequestResponse in the format below?
#ApiOkResponse({
type: User,
})
#ApiBadRequestResponse({
type: {
error: String,
message: ValidationError[]
}
})
#Post('/signup')
signUp(
#Body(ValidationPipe) authCredentialsDto: CredentialsDTO
): Promise<User> {
return this.userService.signUp(authCredentialsDto)
}
From what I understand swagger doesn't know how to work with interfaces instead I have to use classes. Is there a simple way to document bad request response triggered by ValidationPipe. This is all native #nestjs behavior so I would assume there must be an easy solution.
This is what gets actually returned from API:
"statusCode": 400,
"error": "Bad Request",
"message": [
{
"target": {
"username": "somename",
"password": "****"
},
"value": "****",
"property": "password",
"children": [], // ValidationError[]
"constraints": {
"matches": "password too weak"
}
}
]

Related

Amazon Alexa SetVolume Directive

I'm trying to implement the Alexa.Speaker interface with the Node.js v2 sdk.
When testing, I always get the output: There was a problem with the requested skill's response and this error in my CloudWatch logs:
{
"type": "SessionEndedRequest",
"requestId": "amzn1.echo-api.request.bf854d70-70c1-4e7f-b2b0-76c4574244a5",
"timestamp": "2018-10-22T16:58:12Z",
"locale": "en-US",
"reason": "ERROR",
"error": {
"type": "INVALID_RESPONSE",
"message": "An exception occurred while dispatching the request to the skill."
}
}
Here's my code.
return handlerInput.responseBuilder
.addDirective({
type: 'Alexa.Speaker',
name: 'SetVolume',
payload: {
volume: volume,
},
token: 'correlationToken',
})
.getResponse();
I've implemented the Connections.SendRequest interface in this way before, so I'm not sure what's wrong/different with Alexa.Speaker.

Sequelize - get proper path while validating associations of a model

I'm using Sequelize as an ORM for my project. I have this structure:
const Event = sequelize.define('event', {
// fields defined
});
const Question = sequelize.define('question', {
description: {
type: Sequelize.STRING,
allowNull: false,
defaultValue: '',
validate: {
notEmpty: { msg: 'Description should be set.' }
},
},
// other fields defined
});
Event.hasMany(Question);
Question.belongsTo(Event);
Then I create an instance of the Event model, with associate, like that:
const body = {
questions: [
{ description: '' } // is obviously invalid
],
// some other fields
}
const newEvent = await Event.create(body, {
include: [ Question ]
});
If I have validation errors for the Event instance itself, it returns SequelizeValidationError where I can see the path attribute for each ValidationErrorItem. However, when I have the validation error on a child model, the path attribute for this validation error is unclear:
{
"message": "Description should be set.",
"type": "Validation error",
"path": "description",
"value": "",
"origin": "FUNCTION",
"instance": {
"required": true,
"id": null,
"description": "",
"event_id": 60,
"updated_at": "2018-06-11T12:25:04.666Z",
"created_at": "2018-06-11T12:25:04.666Z"
},
"validatorKey": "notEmpty",
"validatorName": "notEmpty",
"validatorArgs": [
{
"msg": "Description should be set."
}
],
"__raw": {
"validatorName": "notEmpty",
"validatorArgs": [
{
"msg": "Description should be set."
}
]
}
The problem is, it's unclear what caused this error and which child is invalid. When I've used Mongoose as an ORM, if I'd do the same, the path attribute would be equal to something like questions.0.description, and that is way more clear, that way you can see which child is invalid.
So, my question is: is there a way to set up the path attribute while validating the child models?
Apparently it's not presented yet, I've filed an issue on Sequelize repo, here it is: https://github.com/sequelize/sequelize/issues/9524

Dialogflow API V2 largeImage for MediaObject not working

I recently switched from the V1 to V2 for dialogflow and I'm updating my webhook.
I use mediaObjects with large Images in my agent as a personal taste.
Unfortunately I can't seem to make it work for the V2.
My current code for the media object is this:
conv.ask(new MediaObject({
name: 'Name',
largeImage: new Image({
url: 'https://[...].jpg',
alt: 'alternative'
}),
url: 'https://[...].mp3',
description: 'description'
}));
As you can see, I used the largeImage field, as I found it in the JSON section of Google's example . As the documentation is inexistant, I'm checking the node.js library for information and I verified that the largeImage field extends the Image interface so it should be correct.
It works when I switch largeImage for Icon but I don't like it.
My JSON response is like this:
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "text"
}
},
{
"mediaResponse": {
"mediaType": "AUDIO",
"mediaObjects": [
{
"contentUrl": "https://[...].mp3",
"description": "description",
"name": "name"
}
]
}
}
],
"suggestions": [
{
"title": "Not yet implemented"
}
]
},
"userStorage": "{\"data\":{}}"
}
}
For some reason the largeImage field doesn't appear in my JSON but there isn't any error appearing anywhere.
Some of the APIs in JSON do not match the Node.js parameters. For example, largeImage in JSON is actually image in the MediaObjectOptions definition.

Sails swagger api documentation

I am using sails in my node js application. And want to implement swagger api documentation. And I follow Swagger Sails JS document. I got the result from my api doc. And my expected result from api doc . I have write the route in router.js file like below
'post /login': {
controller: 'user/UserController',
action: 'login',
skipAssets: 'true',
//swagger path object
"get": {
"tags": [
"Users"
],
"description": "Get a login user data",
"parameters": [{
"email": "abc#gmail.com",
"password": "12345678y",
"deviceToken": "12345678y",
"deviceType": 2
}],
"responses": {
"200": {
"statusCode": 0,
"status": true,
"message": "string",
"result": {}
}
}
}
}
If I had write wrong in my routes. Then how to write the routes, so that I will get my expected result from api docs?
Thanks!
You can try using this.
And I suppose router file should be like this:
'post /login': {
controller: 'user/UserController',
action: 'login',
skipAssets: 'true',
swagger: {
methods: ["get"],
tags: ["Users"],
description: "Get a login user data",
parameters: [{
email: "abc#gmail.com",
password: "12345678y",
deviceToken: "12345678y",
deviceType: 2
}],
responses: {
'200': {
statusCode: 0,
status: true,
message: "string",
result: {}
}
}
}
}

Getting started with FortuneJS

Evening All,
I'm hoping that this is me making a school-boy error. Trying to 'get started' with fortuneJS but having an issue whilst trying to create a new resource.
So, I've setup fortune as described on their homepage. I've opted to use their JSON API plugin, again setup as per their repo.
I'm using Postman to test out the server I've created and I can create a 'user' resource no problem with the following:
{
"data": {
"type": "user",
"attributes": {
"name": "Andrew"
}
}
}
That works fine and I get a response as follows:
{
"data": {
"type": "users",
"id": "37446bbc",
"attributes": {
"name": "Andrew"
},
"relationships": {
"posts": {
"links": {
"self": "http://localhost:1337/users/37446bbc/relationships/posts",
"related": "http://localhost:1337/users/37446bbc/posts"
},
"data": []
}
},
"links": {
"self": "http://localhost:1337/users/37446bbc"
}
}
}
Now, I need to try and create the 'post' resource. Following the JSON API specification I'm posting the following payload:
{
"data": {
"type": "posts",
"attributes": {
"message": "This is my first post"
},
"relationships": {
"author": {
"data": { "type": "users", "id": "37446bbc" }
}
}
}
}
All I get back from that is:
{
"errors": [
{
"title": "Error",
"detail": "An internal server error occurred."
}
]
}
I've debugged by placing a console log of the 'error' on line 118 in node_modules/fortune/dist/lib/dispatch/index.js which shows this error:
[TypeError: Cannot set property 'user' of undefined]
Any advice or guidance you can offer would be greatly appreciated. Hopefully it's just me!
I'm using babel-node app.js to get this running. To save you time, I've thrown up the code onto a public repo
It seems that the actual error message needs to be relayed to the client. You can do so by attaching a catch to the HTTP listener:
const server = http.createServer((request, response) =>
fortune.net.http(store)(request, response)
.catch(error => console.log(error.stack)))
What I found when I recreated the steps was this:
Error: A related record for the field "author" was not found.
However, since it is a generic Error and not a typed error that Fortune uses internally, it is hidden from the client.
So by setting the correct value for the author id, it was able to create a record with that association successfully.
Future versions will be patched so that this informative error message gets shown.
The originally posted question works fine, the version of node was causing an error. Upgrading to v4.2.1 resolved the issue.

Resources