Mule#4: RAML not able to parse JSON in escape characters - bad-request

I have following schema declared in RAML 1.0
body:
application/json:
type: object
properties:
region:
example:
strict: false
value: NA
type: string
required: true
country:
description: Country name
example:
strict: false
value: US
type: string
required: true
orders:
type: array
items:
properties:
orderName:
example:
strict: false
value: "toys"
type: string
maxLength: 20
required: false
orderNumber:
example:
strict: false
value: order12
type: string
maxLength: 25
required: false
maxItems: 100
required: true
When I am sending the below JSON request
{
"region": "South America",
"country": "US",
"orders": [
"{\n \"orderNumber\": \"ORD0118\",\n \"orderName\": \"toys\"\n}",
"{\n \"orderNumber\": \"ORD0119\",\n \"orderName\": \"pens\"\n}",
"{\n \"orderNumber\": \"ORD0120\",\n \"orderName\": \"pencils\"\n}"
]
}
In batch when I am aggregating message and concatenating the payload, the payload was getting formatted as above.
I am seeing a bad request error
Position: Line 0, Column 0\n/orders/0 expected type: JSONObject, found: String Location: Position: Line 0, Column 0\n/orders/1 expected type: JSONObject, found: String Location: Position: Line 0, Column 0\n/orders/2 expected type: JSONObject, found: String Location: Position: Line 0, Column 0",
Please help me in updating RAML to accept the JSON in escape characters as well.

The payload's orders attribute is a list of strings, not of objects, because the members of the array are 'escaped'. Depending on what you intend to do, you can change the RAML to set the array to an array of strings, or convert somehow the strings to the objects the RAML expects.
For the former replace the definition of orders by something like:
orders:
type: string[]
If you want to do the later the following DataWeave script will transform the list in the expected objects:
%dw 2.0
output application/json
---
{
region: payload.region,
country: payload.country,
orders: payload.orders map read($,"application/json")
}
Output:
{
"region": "South America",
"country": "US",
"orders": [
{
"orderNumber": "ORD0118",
"orderName": "toys"
},
{
"orderNumber": "ORD0119",
"orderName": "pens"
},
{
"orderNumber": "ORD0120",
"orderName": "pencils"
}
]
}

Enabling the preserve MIME types in batch aggregator solved this issue.

Related

GraphiQL Mutation: How can I ignore other objects in query variables

Currently having hard time setting up my end points clerk to hasura.
I am absolute new to this platform specially at GraphiQL and just following documentations and youtube video
What I am trying to do is import/insert specific data i neeed only from clerk. Here's the sample query variables:
{
"data": {
"birthday": "",
"created_at": 1654012591514,
"email_addresses": [
{
"email_address": "example#example.org",
"id": "idn_29w83yL7CwVlJXylYLxcslromF1",
"linked_to": [],
"object": "email_address",
"verification": {
"status": "verified",
"strategy": "ticket"
}
}
],
"external_accounts": [],
"external_id": "567772",
"first_name": "Example",
"gender": "",
"id": "user_29w83sxmDNGwOuEthce5gg56FcC",
"last_name": "Example",
"last_sign_in_at": 1654012591514,
"object": "user",
"password_enabled": true,
"phone_numbers": [],
"primary_email_address_id": "idn_29w83yL7CwVlJXylYLxcslromF1",
"primary_phone_number_id": null,
"primary_web3_wallet_id": null,
"private_metadata": {},
"profile_image_url": "https://www.gravatar.com/avatar?d=mp",
"public_metadata": {},
"two_factor_enabled": false,
"unsafe_metadata": {},
"updated_at": 1654012591835,
"username": null,
"web3_wallets": []
},
"object": "event",
"type": "user.created"
}
What I only need to this object is content inside of the "data" is: created_at, first_name, user_id, updated_at, profile_image_url
The GraphiQL Query I did is:
mutation CreateUser(
$created_at: String,
$first_name: String,
$user_id: String,
$updated_at: String,
$profile_image_url: String
)
{
insert_users_one(object:
{
created_at: $created_at,
first_name: $first_name,
user_id: $user_id,
updated_at: $updated_at,
profile_image_url: $profile_image_url,
}) {
created_at
first_name
user_id
updated_at
profile_image_url
}
}
Which throwing error of:
{
"errors": [
{
"extensions": {
"code": "validation-failed",
"path": "$"
},
"message": "unexpected variables in variableValues: object, type, data"
}
]
}
I tried using other method like this:
mutation CreateUser($data: users_insert_input!) {
insert_users_one(object: $data) {
created_at
first_name
user_id
updated_at
profile_image_url
}
}
But it is still having error because of object and type fields
{
"errors": [
{
"extensions": {
"code": "validation-failed",
"path": "$"
},
"message": "unexpected variables in variableValues: object, type"
}
]
}
Here's a sample of GraphQL type:
//is this how you break things down?
type Mutation {
data(
created_at: Int
first_name: String
id: String
updated_at: Int
profile_image_url: String
): Data
}
//this is what i will send in the database, things that I only need
type Verification {
status: String
strategy: String
}
type EmailAddresses {
email_address: String
id: String
object: String
verification: Verification
linked_to: [String]
}
type Data {
birthday: String
created_at: Int
external_id: String
first_name: String
gender: String
id: String
last_name: String
last_sign_in_at: Int
object: String
password_enabled: Boolean
primary_email_address_id: String
primary_phone_number_id: String
primary_web3_wallet_id: String
profile_image_url: String
two_factor_enabled: Boolean
updated_at: Int
username: String
web3_wallets: [String]
phone_numbers: [String]
external_accounts: [String]
email_addresses: [EmailAddresses]
}
type AutogeneratedMainType {
object: String
type: String
data: Data
}
I was expecting based on documents, It will ignore aren't included data.
Visit Github Discussions here
Context about the error
This is error you are receiving is based on this graphql spec - https://spec.graphql.org/June2018/#sec-Input-Objects . More over there is also a different spec for validation against variables here - https://spec.graphql.org/June2018/#sec-All-Variables-Used
TLDR; Using variable which isn’t defined in operation, will result into “unexpected variableValues” error. In your case apart from data , you have type and object as variables in your query variables object which is not defined in operation itself. Remember that query variables is an “object” expecting the variable key-values in it.
Workaround
Cleanest way to do this is to sanitize your object (which you will pass in query variables) by either creating a new object from it and passing data to it or either you remove the unnecessary fields from it which are not defined in operation. You could just delete the properties of that object. Consider yourObject containing data,type and object fields. Then you can do delete yourObject.type and delete yourObject.object. And then pass it.
This workaround is intended for client side code. But there's no exception for graphiQL explorer as that error would be thrown upon undefined variables in operation. If trying via graphiQL explorer, you would manually need to not pass those variables in query variables scope.
Conclusion
This behavior is in compliant with this graphql spec and not with Hasura directly, so we would suggest you to go through those graphql spec links and understand the aspect of it.

Duplicate error even though collection is empty

I try to insert multiple documents into my MongoDB collection, but whatever I do, I get a duplicate error. I made sure that there should be no duplicates possible by dropping the whole collection.
I tried it with .insertMany(), .save(), .create() - none of them do work. Though the docs get inserted, I still get the duplicate error 11000.
My function to insert the docs:
Words.prototype.addManyGeneralWordsEN = async function(words) {
await generalWordEN.create(words).then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err.code)
})
}
// add words to database
await this.addManyGeneralWordsEN(wordsToAdd)
My schema:
const generalWordENSchema = new mongoose.Schema(
{
german: {
type: String,
required: true
},
english: {
type: String,
required: true
},
partOfSpeech: {
required: true,
type: String
},
example: {
default: null,
type: String,
},
defintion: {
default: null,
type: String,
},
image: {
default: null,
type: String,
},
audio: {
default: null,
type: String,
},
level: {
default: null,
type: Number,
},
}
)
generalWordENSchema.index({ german: 1, english: 1, partOfSpeech: 1}, { unique: true })
module.exports = generalWordENSchema
My sample data:
[
{
"english": "clothes",
"german": "Kleidung",
"partOfSpeech": "noun",
"example": "My wife's wardrobe is filled with beautiful clothes.",
"definition": "",
"image": "",
"audio": "",
"level": ""
},
{
"english": "men's clothing",
"german": "Herrenbekleidung",
"partOfSpeech": "noun",
"example": "Men's clothing is on the second floor.",
"definition": "",
"image": "",
"audio": "",
"level": ""
}
]
The problem is probably on this line
generalWordENSchema.index({ german: 1, english: 1, partOfSpeech: 1}, { unique: true })
You created an index for the collection and used partOfSpeech as unique, but you have two documents with the same value noun.
It should work if you change it to:
generalWordENSchema.index({ german: 1, english: 1 }, { unique: true });
You also have a typo on the Schema declaration that might cause you different issues. You typed defintion instead of definition.

openapi 3.0: how to add examples of objects having nested objects inside it?

I want to add examples of my response schema in openapi 3.0 YAML. I have went through the idea on link https://swagger.io/docs/specification/adding-examples/ but my issue is that my response schema object contains nested objects inside it. Can anyone help and guide me about how to add example while having nested objects?
You can define a response example in two ways.
Let this is your nested json object response :
{
"status": true,
"data": {
"storeId": "string",
"message": "string"
}
}
Method 1 : Here in parameter definition itself you can add the example
myschema:
type: object
properties:
status:
type: boolean
required: true
example: true
data:
type: object
properties:
"message":
type: string
example: Success
"Id":
type: string
example: 1234
Method 2 : Here after the property definition you can define an example: tag like this
myschema:
type: object
properties:
status:
type: boolean
required: true
data:
type: object
properties:
message:
type: string
Id:
type: string
example:
status: true
data:
Id: '1234'
message: success

Cosmos DB query without knowing the key for object

Single document example:
{
"id" : "xxxxxx",
"properties": {
"a_prop": {
type: "names",
value: "John",
},
"b_prop": {
type: "score",
value: 5.5,
},
"c_prop": {
type: "names",
value: "Steve",
}
}
}
Question - how can I get documents that has at least one property with type "names" ?
Struggle is that I cannot know before that property "a_prop" is a type of "names".
It's no fun to query when your model has collections of objects with unknown, arbitrary keys. Consider changing model to have known keys and store the unknowns as property values. For example, changing properties to an array of items:
{
id: "xxxxxx",
properties: [
{
name: "a_prop",
type: "names",
value: "John",
},
{
name: "b_prop",
type: "score",
value: 5.5,
},
{
name: "c_prop",
type: "names",
value: "Steve",
}
]
}
Now the array-based query for items with a property of type "names":
SELECT * FROM c
WHERE ARRAY_CONTAINS(c.properties, {"type": "names"}, true)
See also discussion for this question.

MongoDB, Express + GraphQL server: Updated data model with new fields, but queries do not pick up new fields

I created a GraphQL server in combination with Express + MongoDB. I started with the following data model:
const AuthorSchema = new Schema({
name: { type: String, required: true },
age: { type: Number, required: true },
});
Queries + Mutations are working, but I decided to add more fields to the data model:
const AuthorSchema = new Schema({
name: { type: String, required: true },
age: { type: Number, required: true },
bio: { type: String, required: true },
picture: { type: String, required: true }
});
I can add a new author through a mutation with the new fields, but for some reason, queries will not return the new fields.
{
"errors": [
{
"message": "Cannot query field \"bio\" on type \"Author\".",
"locations": [
{
"line": 3,
"column": 5
}
]
}
]
}```
Your GraphQL types are not the same as your Mongoose schemas. If you add a field to AuthorSchema schema and want to also expose this as a field on your Author type, then you need to explicitly define the field in your GraphQL schema.