Subscription in GraphQL - graphql

Help me, I'm working with graphQl and I need a request like subscription. In the documentation I have one "event" method. And how can I, for example, subscribe to the second method "AddressUpdated"?

Related

apollo graphql server subscription - send only if data differs

So I created a subscription in apollo server.
i have my data for that request coming from multiple classes, nested in each other, and this works just fine.
But if I would like apollo to only send out the message if the values the client requested actually changed from the last update.
I can't just cache and compare the last sent object, as I don't know which fields this specific connection is interested in.
Is there a hook or something, that would let me compare the current "over the wire" message before it is sent, so I could compare it with the last "over the wire" message and decide if I actually want to send it?
Putting it in example let's say I have a data structure defined:
{
foo: "valueA",
bar: "valueB"
}
If I were to subscribe with one client to foo and another client to bar, and valueB got updatet to valueC, I would want only the client subscribed to bar to get an update, as the message for the client subscribed to foo would be the same as before.
While I could try to manually filter the data to recreate what would actually be sent to the specific client, this would be sort of redundant, as apollo already does this. Much rather I'd like to intercept the JSON message which gets sent over the websocket, compare it with a stored copy of the last message and decide whether I actually want to send it or to silently discard it.
Also I'm not sure how to find out, which fields the client subscribed to, but then again, I really don't want to go down that route recreating functionality apollo already has built in.
I'm not an expert in apollo graphql by any stretch of the imagination, but I had encountered some cases that could help you with this.
What I'd check first though, is wether Apollo server supports hot/cold subscriptions, but the truth is, that doesn't help much in a case of many connections.
What you should look into is a context of a connection. If it works as I think it works you should be able to create a custom resolver that'd do something along the lines of:
export const SomeResolver = {
Subscription: {
subscribeToSomeMessages: {
subscribe: withFilter(
(rootValue, args, context, info) => {
return pubsub.asyncIterator(["YOUR EVENT"])
},
(payload, variables, context, info) => {
{here compare payload with context}
{update context with new value}
return {if values differ}
}
)
},
...
You can then pass this resolver into ApolloServer initialisation block.
Hope that helps and gives you something to start with

Is it possible to map a subscription parameter to an array at the mutation output?

I have a theoretical question. As I know subscription parameters must exist as a field in the returning type of the mutation. This means that the type of parameter must also match the type of the field in the returning object of the mutation. Am I right? Suppose I get an array with channels ids in the mutation response. I only send one channel id as a parameter in the subscription. Is it possible to map a subscription parameter to an array at the mutation output? If the channel id exists in the array (field channelsIds), the subscription must work. Is it possible to write this logic in the scheme itself, or is it technically impossible?
GraphQL schema:
schema {
mutation: Mutation
subscription: Subscription
}
type Mutation {
testMutation(input: TestMutationInput): TestMutationOutput
}
type TestMutationOutput {
channelsIds: [String!]!
userId: String!
userEmail: String
userPhoneNumber: String
}
type Subscription {
watchTestMutation(channelId: String!): TestMutationOutput
#aws_subscribe(mutations: ["testMutation"])
}
If I understand you correctly you want to filter based on if the mutation's returned value is in an array that is passed as an argument to the subscription. Sorry to say that is not possible at this time. Subscription filters only evaluate to true or false and cannot accommodate any logic other than that.
At the end of October 2020, I contacted AWS support for advice on this issue. I think this answer may be useful to someone, so I post their answer.
Please allow me to inform you that the use-case that you have
mentioned in the case is currently not possible via AppSync. I
understand that the lack of the feature may be causing inconvenience.
There is an internal feature request already with the AppSync team to
incorporate this feature and I have added a +1 on your behalf. It is
worth noting, that once this feature request is with the team, it will
be up to the team as to if/when this potential infrastructure feature
is implemented, and because of the limited visibility into the
progress of internal development processes, I won’t be able to provide
an ETA regarding its release. I would request you to keep an eye on
the what's new page or the AWS Blogs as all new feature requests and
enhancements are posted there[1-3].
However we can suggest a couple of workarounds in this case:
Filter the required fields on client side itself after receiving the values on the client-side from AppSync.
If the values to be filtered are very limited we can use a fake mutation made with the help of a resolver mapped to “None” Data
source. In this flow, we would create a lambda function that uses a
DynamoDB stream as the trigger. The Lambda function is triggered
whenever there's an update to the DynamoDB table.

We can then include logic in the Lambda function to filter the
required fields and perform a mutation to AppSync. In AppSync, the
mutation which was called by lambda would configured using a resolver
mapped to a “None” Data source. The None data source type passes the
request mapping template directly to the response mapping template.
And when we subscribe to this mutation, we will directly get the
filtered data from Lambda that was used to call this mutation. Please
refer to [4] for a step-by-step description of this process.
But please note that this workaround is cumbersome and would require a lot of changes if the required field values keep changing. Workaround 1(handling it on the client-side) is usually the preferred way to handle this use-case.
Resources:
[1] https://blogs.amazon.com/
[2] https://aws.amazon.com/new/
[3] https://aws.amazon.com/releasenotes/
[4] https://aws.amazon.com/premiumsupport/knowledge-center/appsync-notify-subscribers-real-time/

Graphql Apollo Optimistic UI pattern - handle actual result?

We are following the optimistic ui pattern (http://dev.apollodata.com/react/optimistic-ui.html) with the apollo graphql client. Is there a way to handle the actual result from the server? For example, if the server did error on the mutation, we would like to notify the user. Is there a place to get the real result of the mutation?
The mutation returns a Promise. So you can handle the result from the server using than and catch.
If you are using the update functionality of the mutation definition you could use the catch to handle a server error. To get the error as object you could use errorResponse = JSON.parse(JSON.stringify(mutationError))

Where do I find the workflow id of an automation in Mailchimp?

I would like to use Mailchimp Api 3.0 to add a subscriber to an automation workflow, but I can't find where the workflow_id or workflow_email_id are located... this is from the documentation:
POST /automations/{workflow_id}/emails/{workflow_email_id}/queue Add a subscriber to a workflow email
http://developer.mailchimp.com/documentation/mailchimp/reference/automations/emails/queue/
Can anyone tell me to find it? It's probably somewhere really obvious. I mean the list_id is well covered, but I can't find any info about this.
I found this confusing as well. Here is how I got the answer:
Send a GET request to https://us9.api.mailchimp.com/3.0/automations to find the workflow_id
With the workflow_id, send a GET request to https://us9.api.mailchimp.com/3.0/automations/<workflow_id>/emails to find the workflow_email_id. The workflow_email_id will be the "id" in the array that's returned.
From there you can make POST requests to https://us9.api.mailchimp.com/3.0/automations/<workflow_id>/emails/<workflow_email_id>/queue
Keep in mind you might need to subscribe an email address to a list first for the post request to work. To subscribe you can use: https://us9.api.mailchimp.com/3.0/lists/<list_id> with your data:
{
"members": [{
"email_address" : "emailaddress#whatever.com",
"status": "subscribed"
}]
}
The answer is found in the official mailchimp knowledge base: It explains that you simply go into the workflow and read the id from the URL.
Other ways to get id information about anything:
Using the API endpoint, detailed here: http://developer.mailchimp.com/documentation/mailchimp/reference/automations/
You'll see that the Response body parameters return everything about the automations, including the id.
Probably the easier way: use the developer playground https://us1.api.mailchimp.com/playground/?_ga=1.218336095.774374564.1480036371
So, once you set up your lists and automations, go into the playground, and you'll find all the ids you'll need for everything.

OpenLayers: value of Event parameter in OpenLayers.Event.triggerEvent

I'm looking at the
documentation
for triggering events in OpenLayers. It lists triggerEvent as taking in a type:String argument and a evt:Event argument. I understand what the type parameter is, but what object is the Event object? I can't find a clear example.
If it is relevant, I am working on an interface between Google Maps v3 and OpenLayers, and I'm trying to come up with a way so that I can have a the same API interface to calls to:
google.maps.event.trigger(instance:Object, eventName:String, var_args:*)
openLayersObj.events.triggerEvent(type:String, evt:Event)
Doc is wrong. It should be Event || object. Object that will be args passed to the listeners callback.
Look at the source: https://github.com/openlayers/openlayers/blob/master/lib/OpenLayers/Events.js#L820
Example of use: https://github.com/openlayers/openlayers/blob/master/lib/OpenLayers/Map.js#L1042

Resources