Customize AWS-Appsync subscription response data - graphql

In my case, I have an app that users can subscript to some in-app events.
I want to call a mutation from one of my microservices and send several user ids as a list to the mutation, and then all clients that subscript to that mutation receive '[1]'.
schema
type Mutation {
setUsersAlarm(user_id: [Int]): UserIDList
}
type Subscription {
subscripesetUsersAlarm: UserIDList
#aws_subscribe(mutations: ["setUsersAlarm"])
}
type UserIDList {
id_list: [Int]
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
Mutation Resolver
request template
{
"version": "2017-02-28",
"payload":$util.toJson($context.args["user_id"])
}
response template
{
"id_list":$util.toJson($context.result)
}
Subscription Resolver
request template
{
"version": "2017-02-28",
"payload": {
"hello": "local",
}
}
response template
$extensions.setSubscriptionFilter({
"filterGroup": [
{
"filters" : [
{
"fieldName" : "id_list",
"operator" : "contains",
#* I can get the value from cognito or from
user input arguments*#
"value" : 10
}
]
}
]
})
#set ($myList = [1])
#set( $ctx.result.id_list =$myList)
$util.toJson($ctx.result)
Query
subscription MySubscription {
subscripesetUsersAlarm {
id_list
}
}
mutation MyMutation {
setUserRefreshToken(user_id: [10, 12]) {
id_list
flg
}
}
Output of mutation
{
"data": {
"setUsersAlarm": {
"id_list": [
10,
12
]
}
}
}
Output of subscription
I want to receive the below result in subscription:
{
"data": {
"subscripesetUsersAlarm": {
"id_list": [1]
}
}
}
but I receive this:
{
"data": {
"subscripesetUsersAlarm": {
"id_list": [
10,
12
]
}
}
}
I want to customize the subscription response depending on my clients

Related

Using multiple mutations in one call

I have written my first script that utilises GraphQL (Still a learning curve)
Currently i am making 3 calls using GraphQL,
First is a product lookup,
Second is a Price Update,
Third is a Inventory Update.
To reduce the number of calls to the end point i wanted to merge both Price update and Inventory, But i am having 0 luck, i dont know if its bad formatting.
Here is my GraphQL Code (I am using Postman to help ensure the schema is correct before taking it to PHP)
mutation productVariantUpdate($input: ProductVariantInput!) {
productVariantUpdate(input: $input) {
product {
id
}
productVariant {
id
price
}
userErrors {
field
message
}}
second: inventoryActivate($inventoryItemId: ID!, $locationId: ID!, $available: Int) {
inventoryActivate(inventoryItemId: $inventoryItemId, locationId: $locationId, available: $available) {
inventoryLevel {
id
available
}
userErrors {
field
message
}
}
}
}
Variables:
{
"inventoryItemId": "gid://shopify/InventoryItem/XXXXXXXXXXX",
"locationId": "gid://shopify/Location/XXXXXXXXXX",
"available": 11 ,
"input": {
"id": "gid://shopify/ProductVariant/XXXXXXXXX",
"price": 55
}
}
Error i keep getting:
{
"errors": [
{
"message": "Parse error on \"$\" (VAR_SIGN) at [29, 29]",
"locations": [
{
"line": 29,
"column": 29
}
]
}
]
}
The way that you'd go about this is by specifying all your arguments at the root of your mutation, just like you did for ProductVariantInput:
mutation batchProductUpdates(
$input: ProductVariantInput!
$inventoryItemId: ID!
$locationId: ID!
$available: Int
) {
productVariantUpdate(input: $input) {
product { id }
productVariant { id price }
...
}
inventoryActivate(
inventoryItemId: $inventoryItemId
locationId: $locationId
available: $available
) {
inventoryLevel { id available }
...
}
}
Here's an example how this would work if you were to use fetch in JavaScript:
fetch("https://example.com/graphql", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `
mutation MyMutation($firstId: Int, $secondId: Int) {
m1: ToggleLike(id: $firstId) {
id
}
m2: ToggleLike(id: $secondId) {
id
}
}
`,
variables: {
firstId: 1,
secondId: 2
}
})
})
Hope this helps.

does reportStateAndNotification support multiple device state reporting?

I am trying to report the status of a couple of devices via API and I am getting this error
Request payload:
{
"requestId":"3310672920401175639",
"agentUserId":"5d8f3dd42ce05140dc1c6a20",
"payload":{
"devices":{
"states":[
{
"5de28e041729ec0cb40ba906":{
"on":true
}
},
{
"5df49862f53ffa4c1452a448":{
"on":false,
"brightness":100
}
}
]
}
}
}
Response:
{
"error":{
"code":400,
"message":"Invalid JSON payload received. Unknown name "states" at 'payload.devices': Proto field is not repeating, cannot start list.",
"status":"INVALID_ARGUMENT",
"details":[
{
"#type":"type.googleapis.com/google.rpc.BadRequest",
"fieldViolations":[
{
"field":"payload.devices",
"description":"Invalid JSON payload received. Unknown name "states" at 'payload.devices': Proto field is not repeating, cannot start list."
}
]
}
]
}
}
can "states" hold more than one status of the device? or am I doing something wrong with this?
The states value in the payload should be an object with each unique device id as a key. It should not be returned with these wrapped into an array. So your request payload should look more like this:
{
"requestId":"3310672920401175639",
"agentUserId":"5d8f3dd42ce05140dc1c6a20",
"payload": {
"devices": {
"states": {
"5de28e041729ec0cb40ba906": {
"on": true
},
"5df49862f53ffa4c1452a448": {
"on": false,
"brightness": 100
}
}
}
}
}

GraphQL Mutation with JSON Patch

Are there any data types in GraphQL that can be used to describe a JSON Patch operation?
The structure of a JSON Patch operation is as follows.
{ "op": "add|replace|remove", "path": "/hello", "value": ["world"] }
Where value can be any valid JSON literal or object, such as.
"value": { "name": "michael" }
"value": "hello, world"
"value": 42
"value": ["a", "b", "c"]
op and path are always simple strings, value can be anything.
If you need to return JSON type then graphql have scalar JSON
which return any JSON type where you want to return it.
Here is schema
`
scalar JSON
type Response {
status: Boolean
message: String
data: JSON
}
type Test {
value: JSON
}
type Query {
getTest: Test
}
type Mutation {
//If you want to mutation then pass data as `JSON.stringify` or json formate
updateTest(value: JSON): Response
}
`
In resolver you can return anything in json format with key name "value"
//Query resolver
getTest: async (_, {}, { context }) => {
// return { "value": "hello, world" }
// return { "value": 42 }
// return { "value": ["a", "b", "c"] }
// return anything in json or string
return { "value": { "name": "michael" } }
},
// Mutation resolver
async updateTest(_, { value }, { }) {
// Pass data in JSON.stringify
// value : "\"hello, world\""
// value : "132456"
// value : "[\"a\", \"b\", \"c\"]"
// value : "{ \"name\": \"michael\" }"
console.log( JSON.parse(value) )
//JSON.parse return formated required data
return { status: true,
message: 'Test updated successfully!',
data: JSON.parse(value)
}
},
the only thing you need to specifically return "value" key to identify to get in query and mutation
Query
{
getTest {
value
}
}
// Which return
{
"data": {
"getTest": {
"value": {
"name": "michael"
}
}
}
}
Mutation
mutation {
updateTest(value: "{ \"name\": \"michael\" }") {
data
status
message
}
}
// Which return
{
"data": {
"updateTest": {
"data": null,
"status": true,
"message": "success"
}
}
}

how to return customize data in prisma subscription

I am learning graphql & prisma and I came across a question on prisma subscription.
I want to return an item list whenever there is a creation or update on Item. So this is my code which not works.
scheme.graphql
# import Item from "./generated/prisma.graphql"
type Subscription {
todoItems: TodoItems
}
type TodoItems {
items: [Item!]!
}
resolver
const Subscription = {
todoItems: {
subscribe: async (parent, args, context, info) => {
const itemSubscription = await context.db.subscription.item({
where: { mutation_in: ['CREATED', 'UPDATED'] },
}, info);
return itemSubscription;
},
resolve: async (payload, args, context, info) => {
const items = await context.db.query.items({ type: 0, orderBy: 'updatedAt_DESC' }, info);
return { items };
},
},
}
module.exports = {
Subscription,
}
and in graphql playground,
subscription{
todoItems{
items{
title
}
}
}
it gives the error:
{
"errors": [
{
"message": "Anonymous Subscription must select only one top level field.",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"todoItems"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"Error: Anonymous Subscription must select only one top level field.",
" at asErrorInstance (d:\\git\\inote\\node_modules\\graphql\\execution\\execute.js:489:43)",
" at <anonymous>",
" at process._tickCallback (internal/process/next_tick.js:118:7)"
]
}
}
}
]
}
Any idea?
Prisma does not support subscribing item lists. Instead, prisma wants you to subscribe to single item mutations ("created", "updated", "deleted"). As described here.
E.g.
subscription newTodos {
todo(where: {
mutation_in: [CREATED]
}) {
mutation
node {
title
}
}
}
To get "the full list", you have to query on the todos after subscribing to avoid missing events (race condition). As a result you have to manually "sync" the data from the subscription and your query.

How do you filter a list response using a graphql query in Sangria

I am running a graphQL server on Sangria (scala). Here is an example query:
query {
missions {
missionId { id } ,
name
}
}
and a sample response:
{
"data": {
"missions": [
{
"missionId": {
"id": "mission1"
},
"name": "foo"
},
{
"missionId": {
"id": "mission2"
},
"name": "bar"
}
]
}
}
I am looking for a query that filters the list and only returns the element having mission1 as id?
You need implement pagination. Pass limit(pageSize) argument to graphql server resolver. process the datas in server-side.
query {
missions(limit: 1) {
missionId { id } ,
name
}
}
server-side:
const resolvers = {
Query: {
missions: (_, {limit}, ctx) => {
const missions = [];
for(let i = 0; i < limit; i++) {
missions.push(db.missions[i])
}
return missions;
}
}
}
That's graphql ideology, front-end developer define the data structure and what data they want to get.
It's bad idea to query the list data through a http request. And filter the data in front-end using directive or other way of graphql. Waste bandwidth.

Resources