the following if condition does not work:
I still have the possibility to register with numbers instead of strings.
enter image description here
It's likely that req.body.firstName and req.body.lastName are coming in as a stringed numbers e.g.:
{
"firstName": "4",
"lastName": "187"
}
so typeof will still consider them as strings. You can use a regex if you really hate numbers.
const { firstName, lastName } = req.body;
if (firstName.match(/^\d*(\.\d+)?$/) || lastName.match(/^\d*(\.\d+)?$/)) {
return res.status(422).json({
message: 'Name provides letters, not numbers!',
})
}
or I would suggest you use a validation library like Joi or validate.js to avoid building an API with possible security holes.
Related
Given the following GraphQL mutations:
type Mutation {
updateUser(id: ID!, newEmail: String!): User
updatePost(id: ID!, newTitle: String!): Post
}
The Apollo docs state that it's totally possible to perform multiple mutations in one request, say
mutation($userId: ID!, $newEmail: String!, $postId: ID!, $newTitle: String!) {
updateUser(id: $userId, newEmail: $newEmail) {
id
email
}
updatePost(id: $postId, newTitle: $newTitle) {
id
title
}
}
1. Does anyone actually do this? And if you don't do this explicitly, will batching cause this kind of mutation merging?
2. If you perform run multiple things within on mutation, how would you handle errors properly?
I've seen a bunch of people recommending to throw errors on the server so that the server would respond with something that looks like this:
{
errors: [
{
statusCode: 422,
error: 'Unprocessable Entity'
path: [
'updateUser'
],
message: {
message: 'Validation failed',
fields: {
newEmail: 'The new email is not a valid email address.'
}
},
},
{
statusCode: 422,
error: 'Unprocessable Entity'
path: [
'updatePost'
],
message: {
message: 'Validation failed',
fields: {
newTitle: 'The given title is too short.'
}
},
}
],
data: {
updateUser: null,
updatePost: null,
}
}
But how do I know which error belongs to which mutation? We can't assume, that the first error in the errors array belongs to the first mutation, because if updateUser succeeds, the array would simple contain one entry. Would I then have to iterate over all errors and check if the path matches my mutation name? :D
Another approach is to include the error in a dedicated response type, say UpdateUserResponse and UpdatePostResponse. This approach enables me to correctly address errors.
type UpdateUserResponse {
error: Error
user: User
}
type UpdatePostResponse {
error: Error
post: Post
}
But I have a feeling that this will bloat my schema quite a lot.
In short, yes, if you include multiple top-level mutation fields, utilize the path property on the errors to determine which mutation failed. Just be aware that if an error occurs deeper in your graph (on some child field instead of the root-level field), the path will reflect that field. That is, an execution error that occurs while resolving the title field would result in a path of updatePost.title.
Returning errors as part of the data is an equally valid option. There's other benefits to this approach to:
Errors sent like this can include additional meta data (a "code" property, information about specific input fields that may have generated the error, etc.). While this same information can be sent through the errors array, making it part of your schema means that clients will be aware of the structure of these error objects. This is particularly important for clients written in typed languages where client code is often generated from the schema.
Returning client errors this way lets you draw a clear distinction between user errors that should be made visible to the user (wrong credentials, user already exists, etc.) and something actually going wrong with either the client or server code (in which case, at best, we show some generic messaging).
Creating a "payload" object like this lets you append additional fields in the future without breaking your schema.
A third alternative is to utilize unions in a similar fashion:
type Mutation {
updateUser(id: ID!, newEmail: String!): UpdateUserPayload!
}
union UpdateUserPayload = User | Error
This enables clients to use fragments and the __typename field to distinguish between successful and failed mutations:
mutation($userId: ID!, $newEmail: String!) {
updateUser(id: $userId, newEmail: $newEmail) {
__typename
... on User {
id
email
}
... on Error {
message
code
}
}
}
You can get even create specific types for each kind of error, allowing you to omit any sort of "code" field:
union UpdateUserPayload = User | EmailExistsError | EmailInvalidError
There's no right or wrong answer here. While there are advantages to each approach, which one you take comes ultimately comes down to preference.
I have Tried
I have tried this code
`# Type queries into this side of the screen, and you will
# see intelligent typeaheads aware of the current GraphQL type schema,
# live syntax, and validation errors highlighted within the text.
# We'll get you started with a simple query showing your username!
query {
securityAdvisories(orderBy: {field: PUBLISHED_AT, direction: DESC}, first: 2) {
nodes {
description
ghsaId
summary
publishedAt
}
}
}
And got the below response
{
"data": {
"securityAdvisories": {
"nodes": [
{
"description": "In Symfony before 2.7.51, 2.8.x before 2.8.50, 3.x before 3.4.26, 4.x before 4.1.12, and 4.2.x before 4.2.7, when service ids allow user input, this could allow for SQL Injection and remote code execution. This is related to symfony/dependency-injection.",
"ghsaId": "GHSA-pgwj-prpq-jpc2",
"summary": "Critical severity vulnerability that affects symfony/dependency-injection",
"publishedAt": "2019-11-18T17:27:31Z"
},
{
"description": "Tapestry processes assets `/assets/ctx` using classes chain `StaticFilesFilter -> AssetDispatcher -> ContextResource`, which doesn't filter the character `\\`, so attacker can perform a path traversal attack to read any files on Windows platform.",
"ghsaId": "GHSA-89r3-rcpj-h7w6",
"summary": "Moderate severity vulnerability that affects org.apache.tapestry:tapestry-core",
"publishedAt": "2019-11-18T17:19:03Z"
}
]
}
}
}
But i want to get the response for specific security advisory like this
i.e i want to get graphql response for specific id for below example url ID is GHSA-wmx6-vxcf-c3gr
Thanks!
The simplest way would be to use the securityAdvisory() query.
query {
securityAdvisory(ghsaId: "GHSA-wmx6-vxcf-c3gr") {
ghsaId
summary
}
}
If you need to use the securityAdvisories() query for some reason, you simply have to add an identifier:. The following query should get the distinct entry for GHSA-wmx6-vxcf-c3gr.
query {
securityAdvisory(ghsaId: "GHSA-wmx6-vxcf-c3gr") {
ghsaId
summary
}
}
I want to write a JSON API.
My problem is, that sometimes I want to query for an ID, sometimes for a String.
One option would be to add a querystring, for example:
example.com/user/RandomName
example.com/user/1234556778898?id=true
and use it like:
api.get('user/:input', function(req, res) {
if(req.query.id) {
User.find({ '_id': req.params.input }, cb);
} else {
User.find({ 'name': req.params.input }, cb);
}
};
But this seems like bad practice to me, since it leads to a bunch of conditional expressions.
Are there more elegant ways?
I would suggest handling two endpoints. One for getting ALL the users and one for getting a SPECIFC user by ID.
example.com/users
example.com/users/:id
The second endpoint can be used to find a specific user by id.
The first endpoint can be used to find all users, but filters can be applied to this endpoint.
For example: example.com/users?name=RandomName
By doing this, you can very easily create a query in your Node service based on the parameters that are in the URL.
api.get('/users', function(req, res) {
// generate the query object based on URL parameters
var queryObject = {};
for (var key in req.query) {
queryObject[key] = req.query[key];
}
// find the users with the filter applied.
User.find(queryObject, cb);
};
By constructing your endpoints this way, you are following a RESTful API standard which will make it very easy for others to understand your code and your API. In addition, you are constructing an adaptable API as you can now filter your users by any field by adding the field as a parameter to the URL.
See this response for more information on when to use path parameters vs URL parameters.
I have a (simplified) query that looks as follows.
var pageViews = new Keen.Query('count', {
eventCollection: 'Loaded a Page',
groupBy: 'company.id'
});
And use it as follows.
client.run(pageViews, function(result, error) {
// Do something here
});
This will give me the following JSON to work with:
{
"result": [
{
"company.id": 1,
"result": 3
},
{
"company.id": 2,
"result": 11
},
{
"company.id": 3,
"result": 7
}
]
}
However, I would also like to get back the name of each company, i.e. the company.name property. I looked through keen.io's documentation, and I could find no way of doing this. Is there a way to do this? Logically speaking, I don't see any reason why it would not be possible, but the question is if it has been implemented.
Grouping by multiple properties will get you what you're looking for:
var pageViews = new Keen.Query('count', {
eventCollection: 'Loaded a Page',
groupBy: ['company.id','company.name']
});
That being said, it's important to note that Keen is not an entity database. Keen is optimized to store and analyze event data, which is different than entity data. More complex uses of entity data may not perform well using this solution.
This may be a stupid question but I want to ask because it may be an indication of a mistake I may be making.
I just created my first Web API project and started hosting it as a website. Initially, I was getting XML responses, so I added the following line in the Register method:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
I now get JSON results but my JSON results are not nicely formatted. They all come back as a regular string.
I get this:
{ "id": 123, "firstName": "John", "lastName": "Smith",
"gender": "male"}
I've seen a lot of examples where the result looks like this:
{
"id": 123,
"firstName": "John",
"lastName": "Smith",
"gender": "male"
}
Am I doing something wrong?
-- Edit ---
Thank you all for your response.
I wonder if the way I'm returning the data is causing this formatting issue. I'm just returning my POCO class and lettting the Web API handle any serialization. Is this the right way to return my data?
public IHttpActionResult GetSpecifiedPerson(int id)
{
Person user = new Person();
user.PersonId = 1234567;
user.FirstName = "Jane";
user.LastName = "Doe";
return Ok(user);
}
There is nothing wrong with your JSON. When you parse that you won't face any problems.
your JSON result is completely fine. nothing wrong.
most examples are formatted nicely for readability. nothing else