I would like to know what is the best way to handle or to prevent POST requests from a user with a missing body property.
For example, i have a sample DTO like this :
export class SourceDto {
id: string;
name: string;
description: string;
address: string;
agent_id: string;
state: number;
created_at: Date;
updated_at: Date;
}
When sending a post request without the "name" property in the body I am getting a 500 error because my query needs the name property to not be null.
So my question is does NestJs also handle validations to validate if any of the body properties are missing? And instead of returning 500 errors without any info, return an error message that says missing name property?
Related
When I send only one parameter, I got query result like string, not like string[]. This heppend only from UI swagger, if I send from Postman - it works good.
I just want send from swagger-ui one parammeter and got array of string, not string
How I can fix it? Help me please.
Example1: send one paramenter and in my controller I got string like '25'
Example2: when I send 2 parameters in controller I can see array of strings ('25', '21')
export class List {
#ApiProperty({ isArray: true, type: String, required: false })
#IsOptional()
public categories?: string[];
}
You should try to spread your parameter in a const in services
edit:
I don't know how to explain in formal words, but a array of strings of one item, for JAVASCRIPT, seems with the same thing as one string value.
Because array is not a type, but a form of a type....
So, if you, in your controller, before do anything with it, you redeclare as:
#Get(":id")
findManybyId(#Param("id") id: string[]) {
const idArray = [...id];
return await this.service.findManyById(idArray);
}
It will solve your problem about being an array
old answer:
You should try to change in your controller where you make your input decorator.
in your case, i don't know if you are using ID to get, but you must to do as the example:
#ApiOperation({
summary: "Get many categories by ID",
})
async getMany(
#Param("id") ids: string[],
) {
return await this.categoriesService.getMany(id);
}
when you fill a single category the query param will be translated as a string while when you fill in several categories understand it as a array.
to solve this problem I added in DTO :
#Transform(({ value }) => (Array.isArray(value) ? value : Array(value)))
I force the cast to array
this.getView().bindElement({
path: `/Employees('${this._userId}')`,
parameters: { expand: 'aaa,bbb,ccc' },
events: {
dataReceived: (oEvent) => {
this.getView().setBusy(false)
debugger
}
}
});
I can see data in the response of the $batch request.
When I put a breakpoint in the dataReceived function handler, I can also see the data via this.getView().getModel().getProperty(this.getView().getBindingContext().getPath()).
The parameter oEvent.mParameters.data exists, but the value is undefined.
If I leave out expand, the data is set. Do all entities of an associated entityset need to have an association to its parent?
This is by design according to the API reference of dataReceived:
dataReceived
[...] This event may also be fired when an error occurred.
Param
type
description
data
string
The data received; is undefined in error cases
You must have somewhere an error message in the $batch response, or the request was somehow aborted.
The missing data parameter is currently the only documented indicator for a failed request on bindObject/bindElement.
PS: See also https://github.com/SAP/openui5/issues/2263
I have an API which is accepting query param as Object. I am using this to add multiple filters to filter the result.
When I hit the request from swagger, I am getting null for my filter object in the controller.
userFilter is the POJO class. It is used as a query param and in the controller, it is coming as null.
On swagger, it is showing as below
userFilter object is not getting constructed and getting NullPointerException in controller class when trying to access any field from userFilter.
I got the solution from swagger.io.
As per the explanation, content is used in complex serialization scenarios that are not covered by style and explode. For example, if we need to send a JSON string in the query string like so:
filter={"type":"t-shirt","color":"blue"}
In this case, we need to wrap the parameter schema into content/<media-type> as shown below.
We need to add content = {#Content(schema = #Schema(type = "object"))} to the #Parameter.
#Parameter(description = "Filters", required = true, content = {#Content(schema = #Schema(type = "object"))})
In JSON format it will look like below.
parameters:
- in: query
name: filter
# Wrap 'schema' into 'content.<media-type>'
content:
application/json: # <---- media type indicates how to serialize / deserialize the parameter content
schema:
type: object
properties:
type:
type: string
color:
type: string
I'm trying to use GraphQL in iOS with Apollo Client. I have the following mutation:
login(user: String!, password: String!): UserType
and the UserType looks like this:
id: ID
user: String!
password: String!
name: String
lastname: String
email: Email!
groups: [GroupType]
In iOS, I have configured aopllo client as the doc says and is working perfectly, but I don't know how to get access to every field in the response. When the login success I want to read the json I receive as response with the UserType fields, so, I'm doing this:
apolloClient.perform(mutation: loginMutation) {
resultsGQL, error in
...
}
My question is, how can I read every field from resultGQL which belongs to the UserType data defined in my grapql schema?
Regards
The question is not 100% clear, since it is missing some code your mutation: A GraphQL mutation has to return at least one value, which you have to define. Since i'm not sure about your method
login(user: String!, password: String!): UserType
i am giving you a simple example for updating an existing userProfile with a GraphQL mutation and then returning every field being defined in your schema for userType.
Let us assume you have a userType (and therefore know the corresponding userId) and you want to modify the email:
mutation updateUserProfile($id: ID!, $newEmail: String) {
updateUser(id: $id, email: $newEmail) {
id
user
password
name
lastName
email
}
}
As you can see, after executing
updateUser(id: $id, email: $newEmail)
all return values are defined inside the following {...} parentheses and are therefore accessible in your callback variable
resultsGQL
That means:
apolloClient.perform(mutation: loginMutation) { resultsGQL, error in
if let results = resultsGQL?.data {
// "results" can now access all data from userType
}
}
Since you defined all entities of your userType schema to be returned from the mutation, you can access them now in your callback variable.
I got a button where I want to post data to my SAP backend on press-method:
oCellBtnOtherchart.addContent(new sap.ui.commons.Button({
text : "Save",
press : function() {
var sServiceUrl = "/MyEntitSet('0001')";
var oModel = sap.ui.getCore().getModel();
console.log(oModel);
var oParameters = {
"email" : "a",
"lastname" : "b",
"firstname" : "c",
};
oModel.create(sServiceUrl, oParameters);
}
}));
My questions are:
In which method would this request end in backend? I expect MyEntitySet_CREATE_ENTITY()
Why doesnt it work, the error message is: HTTP request failed 405, Method Not Allowed
But why is it 405, is my Service URL Wrong? How do I Post data correctly to the SAP Backend?
SAP Troubleshooting Guide says: 405 Method Not Allowed
o The method specified in the Request-Line is not allowed for the resource
identified by the Request-URI. The response must include an Allow header
containing a list of valid methods for the requested resource. --> This does not help me right now, anybody knows how to include an allow header?
Because there are only few threads on this topic at SO, which in my opinion do not answer the questions I had, I'll share my findings how to pass data to the backend via oModels create method:
First Define a type of your result entity (check your oData-Model to know the attributes, e.g. Name and YourID):
var oEntry = {};
oEntry.YourID = "0001";
oEntry.Name = "Peter";
Then fetch your model:
var oModel = sap.ui.getCore().getModel();
Then execute the create operation thanks to: https://sapui5.netweaver.ondemand.com/docs/api/symbols/sap.ui.model.odata.ODataModel.html
jQuery.sap.require("sap.ui.commons.MessageBox");
oModel.create('/EntitySet', oEntry, null, function(){
sap.ui.commons.MessageBox.show(
sap.ui.commons.MessageBox.alert("Success!");
);
},function(){
sap.ui.commons.MessageBox.alert("Error!");
});
Results in Backend in Method "ENTITYSET_CREATE_ENTITY"-Method, where you can retrieve YourID and Name:
DATA: ls_data TYPE ycl_class_mpc=>ts_entity.
CALL METHOD io_data_provider->read_entry_data
IMPORTING
es_data = ls_data.
WRITE ls_data-name.
WRITE ls_data-yourid.
This example applies to single calls, you can see the result in ABAP is a structure. If you need to pass multiple datasets to the backend you should search for batch processing at https://openui5.hana.ondemand.com/docs/api/symbols/sap.ui.model.odata.ODataModel.html
If you are still looking for a good blog on how to make a batch post then have a look at this post http://scn.sap.com/community/developer-center/front-end/blog/2012/11/18/gateway-batch-calls-from-sapui5