Mule4# Valid DWL to format graphQL request - graphql

I want to consumer graphQl API.
I know we need to use http requester to call graphQl.
I need some info on forming mutation request using dwl.
I was trying to hit this service https://www.predic8.de/fruit-shop-graphql
using below
%dw2.0
outputapplication/json
---
{
"query": "mutation(\$input:addCategoryInput!) { addCategory(input:\$input) { name products { name}} }",
"variables": {
"input": {
"id": 6,
"name": "Green Fruits",
"products": 8
}
}
}
its throwing bad request
But when using below
%dw 2.0
output application/json
---
{
"query": "mutation { addCategory(id: 6, name: \"Green Fruits\", products: 8) { name products { name } }}"
}
its working.
I want to use above format. Are both not valid requests.
Please share me your knowledge or guide me to right blog to refer.

output application/json
---
{
query: "mutation(\$id:Int!,\$name:String!,\$products:[Int]!) { addCategory(id:\$id, name:\$name, products:\$products) { name products { name } } }",
variables: {
id: 6,
name: "Green Fruits",
products: [8]
}
}
Your issue would appear to be more with your GraphQL. Products is defined as [Int]! in the schema, and you need to pass in the individual arguments - I don't see an addCategoryInput defined anywhere in the schema, and addCategory is expecting individual arguments.

Related

Simplest usage of GraphQL using WHERE, AND, OR while using a Query Parameter

I'm creating a search query for a simple search on a site using GraphQL.
I've been looking for the absolutely simplest working examples of GraphQL but the questions/examples I've found on Stack Overflow are either too simple, too specific, or way too technical including too many unnecessary bits from the API.
The patterns of when to use the {}, when to use the where, and when optional naming come into play seem to disrupt the patterns that are explained in the docs.
Any insight here would be much appreciated.
Great question.
Here's how I would start. I will assume you have setup a database with Products and those Products have a name and a description.
First - here's how you get all the products (you will be inputting this into the GraphQL playground).:
query {
allProducts {
name
description
}
}
Second - here's how you get a product with a specific name:
query {
allProducts (where: {name: "Nike Air VaporMax"}){
name
description
}
}
Third - here's how to introduce "contains" as in name or description contains "nike". The _i suffix means case insensitive.
query {
allProducts (where: {name_contains_i: "nike"}){
name
description
}
}
Fourth - here's how to introduce an OR (note the commas and the container curly brackets):
query {
allProducts (where: {
OR: [{description_contains_i:"shoes"}, {name_contains_i:"shoes"}]
}
)
{
name
description
}
}
Fifth - here's how to introduce the AND (same as above, note the comma and the curly brackets):
query {
  allProducts (where: {
AND: [{description_contains_i:"shoes"}, {name_contains_i:"shoes"}]
    }
  )
    {
    name
    description
  }
}
Sixth - here is how to start introducing variables - we'll use this with a WHERE + OR:
query ($varTest: String!) {
allProducts(
where: {
OR: [{ description_contains_i: "shoes" }, { name_contains_i: $varTest }]
}
) {
name
description
}
}
And !important! for the above, you will need to fill in the Query Variables:
{
"varTest": "Nike"
}
In case, you're not familiar with the placement of where to put the Query Variable, it will roughly look like this (look for the second window in which to place the Query Variables.)
Seventh - here is the kicker. You can optionally name these queries. The disruption in the pattern consistency threw me off initially. Let me add it here with a pretty obvious name so you can see it too:
query THIS_IS_MY_COOL_QUERY_NAME($varTest: String!) {
allProducts(
where: {
OR: [{ description_contains_i: "shoes" }, { name_contains_i: $varTest }]
}
) {
name
description
}
}
Eight - bonus. You won't need this BUT I want to introduce it here so it doesn't throw you off in the future. When you submit the query, you can assign your own name for the returned array of returned objects. Don't let this previous sentence confuse you, I'll give you examples of the returned array so it's clear.
Here is the Eight query (don't forget to use a Query Variable as you did in the Seventh example). I'll add a pretty obvious name directly in the query:
query THIS_IS_MY_COOL_QUERY_NAME($varTest: String!) {
resultsWillBeReturnedAsArrayWithThisName: allProducts(
where: {
OR: [{ description_contains_i: "shoes" }, { name_contains_i: $varTest }]
}
) {
name
description
}
}
The results from previous query (Seventh) will look like this:
{
"data": {
"allProducts": [
{
"name": "Air Jordan 1",
"description": "Wow - there are shoes!"
},
{
"name": "Nike Blazer Mid",
"description": "Very nice!"
},
{
"name": "Shoes",
"description": "These are shoes!"
}
]
}
}
But the results from the Eight Query will look like this (notice how the name you introduced will come back to you from GraphQL). :
{
"data": {
"resultsWillBeReturnedAsArrayWithThisName": [
{
"name": "Air Jordan 1",
"description": "Wow - there are shoes!"
},
{
"name": "Nike Blazer Mid",
"description": "Very nice!"
},
{
"name": "Shoes",
"description": "These are shoes!"
}
]
}
}
That should give you a solid building block to understanding GraphQL.

Use Postman to test Appsync Subscription

I have been able to successfully execute Appsync GraphQL queries and mutations from Postman. However, i'm struggling to connect to subscriptions which are websocket urls.
How can I achieve the same ?
Since Postman supports WebSockets testing GraphQL subscriptions is achievable as well. Such a testing requires two steps:
connection to a server,
sending a start message.
Establishing a connection:
Create a new WebSocket request.
Put your server URL ws:// or wss://.
Add custom header parameter Sec-WebSocket-Protocol: graphql-ws. Other headers may depend on your server configuration.
Press the "Connect" button.
When the connection is established we may start a subscription.
In the "New message" field put the command.
Press the "Send" button.
The start message should look like this:
{
"id":"1",
"payload": {
"operationName": "MySubscription",
"query": "subscription MySubscription {
someSubscription {
__typename
someField1
someField2 {
__typename
someField21
someField22
}
}
}",
"variables": null
},
"type": "start"
}
operationName is just the name of your subscription, I guess it's optional. And someSubscription must be a subscription type from your schema.
query reminds regular GraphQL syntax with one difference:
__typename keyword precedes every field list.
For example, the query from the payload in regular syntax looks like the following:
subscription MySubscription {
someSubscription {
someField1
someField2 {
someField21
someField22
}
}
}
Example message with parameters (variables):
{
"id":"1",
"payload": {
"operationName": "MySubscription",
"query": "subscription MySubscription($param1: String!) {
someSubscription((param1: $param1)) {
__typename
someField
}
}",
"variables": {
"param1": "MyValue"
}
},
"type": "start"
}
It also reminds regular GraphQL syntax as described above.
variables is an object with your parameters.
#Vladimir's answer is spot on. Adding a few notes for folks still having trouble.
Full document here # https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html
Step 1 - establish connection:
make sure to base64 encode values in "header" and "payload" querystrings
header example:
{
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com",
"x-api-key":"da2-12345678901234567890123456"
}
payload: You can pass in empty payload
{}
Step 2 - register subscription:
Include the authorization in the message. Escape line feeds properly "\n" throws an error but "\\n" works. it throws the following error - misleading.
Don't forget to stringify value in "data" field.
{
"type": "error",
"payload": {
"errors": [
{
"errorType": "UnsupportedOperation",
"message": "unknown not supported through the realtime channel"
}
]
}
}
{
"id": "2",
"payload": {
"data": "{\"query\":\"subscription onCreateMessage { changeNotification{ __typename changeType from } }\",\"variables\":{}}",
"extensions":{
"authorization":{
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com",
"x-api-key":"da2-12345678901234567890123456"
}
}
},
"type": "start"
}

Consume graphQL API from Mule 4

I want to consumer graphQl API.
I know we need to use http requester to call graphQl.
I need some info on forming mutation request using dwl.
I was trying to hit this service https://www.predic8.de/fruit-shop-graphql
using below
%dw2.0
outputapplication/json
---
{
"query": "mutation(\$input:addCategoryInput!) { addCategory(input:\$input) { name products { name}} }",
"variables": {
"input": {
"id": 6,
"name": "Green Fruits",
"products": 8
}
}
}
its throwing bad request
But when using below
%dw 2.0
output application/json
---
{
"query": "mutation { addCategory(id: 6, name: \"Green Fruits\", products: 8) { name products { name } }}"
}
its working.
I want to use above format. Are both not valid requests.
Please share me your knowledge or guide me to right blog to refer.
Since GraphQL is not a supported format for DataWeave at this time, you have to write the query yourself as a string. You can however use DataWeave to create the body of a POST request for a query.
Example:
%dw 2.0
output application/json
---
{
"query": "mutation(\$schedule:PipelineScheduleCreateInput!) { pipelineScheduleCreate(input:\$schedule) { pipelineScheduleEdge { node { label nextBuildAt cronline } } } }",
"variables": {
"schedule": {
"pipelineID": "UGlwZWxpbmUtLS02MzliNWJjOC0wMGZmLT",
"cronline": "#midnight",
"label": "Nightly build"
}
}
}

grpc/protobuffer ask for specific fields

GraphQL lets you ask for specific fields, the response contains only the fields that you had asked for. For example:
a graphql query like:
{
hero {
name
}
}
will return:
{
"data": {
"hero": {
"name": "R2-D2"
}
}
}
where as a graphQl query like:
{
hero {
name
friends {
name
}
}
}
would return:
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{
"name": "Luke"
},
{
"name": "Han Solo"
},
{
"name": "Leia"
}
]
}
}
}
Is there a similar mechanism/library/pattern that can be used in gRPC to achieve the same?
FieldMask is similar in protobuf. It is a list of fields to retain, so the first example would be paths: "hero.name" and the second would be paths: ["hero.name", "hero.friends.name"].
It is probably most frequently used to specify which fields should be changed in an update. But it can equally be used to specify the fields that should be returned.
The server can either process the FieldMask directly (e.g., only using the listed fields in a SELECT SQL query), or it can retrieve all the information and filter the result using FieldMaskUtil.merge() to copy just the requested fields into a new proto message to return to the client.

Is there any way to query products using dynamic filters in Magento 2.3 graphql endpoint?

I was looking at the new graphql endpoint exposed by Magento 2.3.1 and above at the query for listing products:
query products(
pageSize:6,
currentPage:1,
filter:{
category_id: { eq: "3" }
}
) {
filters {
name
request_var
filter_items_count
filter_items {
label value_string
}
}
items {
id
name
small_image {
url
}
# ...
}
# ...
}
The response body yields products in the items property just as expected and a bunch of custom filters in an array in the filters property which look like this:
"filters": [
{
"name": "Activity",
"request_var": "activity",
"filter_items_count": 12,
"filter_items": [
{
"label": "Outdoor",
"value_string": "5"
},
{
"label": "Yoga",
"value_string": "8"
},
{
"label": "Recreation",
"value_string": "9"
},
// rest of filter values
]
},
// rest of filters
]
Given the fact that those filters are dynamic and user defined is there a way of sending them back with a list products query in graphql? I would expect to have a property somewhere under the products query that could be an array of aforementioned filter objects but so far I haven't found anything neither in the schema nor in the official documentation.
Did anyone have any similar experience with this?
No. Theres no way of getting the filtered options sent back. There are options where you can return the additional filtering abilities (similar to when you are viewing a category page) to return list of ways to filter but nothing that returns the current active filters in place.
{
products(filter: {sku: {like: "%"} } pageSize: 500) {
filters{
request_var
name
filter_items{
label
value_string
}
}
items {
id
sku
name
...
}
}
}

Resources