I'm going crazy over subscriptions with AWS AppSync. My problem is that I can't figure out how to get a filtered subscription. When I pass any arguments into the subscriber, I get nothing in return.
What am I missing?
In schema.graphql my mutation looks like this
testMutation(
id: String!,
val: String!
): TestItem!
My "catch all" subscriber looks like this
subscribeToAllTestMutations: TestItem!
#aws_subscribe(mutations: ["testMutation"])
The problematic subscriber looks like this:
subscribeToTestMutation(id: String!): TestItem!
#aws_subscribe(mutations: ["testMutation"])
When I run this mutation:
mutation {
testMutation(
id: "123-test",
val:"Hey man"
) {
id
val
}
}
I get this response:
{
"data": {
"testMutation": {
"id": "123-test",
"val": "Hey man",
"__typename": "TestItem"
}
}
}
I get the same when I run this:
subscription {
subscribeToAllTestMutations {
id
val
}
}
But when I pass the ID I get nothing, which turns me crazy:
subscription {
subscribeToTestMutation(
id: "123-test"
) {
id
val
}
}
I figured it might have something to do with my mapping templates, but i cannot figure out how to solve it.
I currently, for test purposes, just pass the data through like this with my request mapping template:
{
"version": "2017-02-28",
"payload": $utils.toJson($context.arguments)
}
And, as for resolver mapping template, I just do this:
$utils.toJson($context.result)
Please, if anyone can help me you will save my sanity 🤪
Related
I am following this instruction https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns-content-based-filtering.html#eb-filtering-anything-but to setup a event pattern rule with anything-but like below code:
{
"detail": {
"payload": {
"type": [
{
"anything-but": "test"
}
]
}
}
}
In above example, I set the type field in payload of the event to be anything but test. It works fine if the event has payload->type field. But it doesn't accept the event if it payload doesn't have type field. It seems anything-but filter out none-exist field.
As an example, below event payload is accepted:
{
detail: {
payload: {
name: 'xxx',
type: 'production'
}
}
}
but below event which doesn't have type field is not accepted.
{
detail: {
payload: {
name: 'xxx'
}
}
}
How can I let it support none-exist? I'd like to make it accept event who doesn't have such field.
You have certainly moved on with your life since then... but figured I would drop an answer here for anyone else traversing the interwebs in frustration with EventBridge rules...
In the array you are assigning to type, you can include any number of matching options:
{
"detail": {
"payload":
"type": [
{"anything-but": "test"},
{"exists": false}
]
}
}
}
If you need more complex matching that includes multiple fields existing or not, look into $or
https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns-content-based-filtering.html#eb-filtering-complex-example-or
I have an AppSync API that I'm using for an app. One action I'm trying to do is have a Lambda function that collects certain data fire off a GraphQL mutation, and then have a subscription on my front end collect that data when the mutation is called. This data is ephemeral and I don't want to write it to a database, so I'm trying to set up a "None" data source in AppSync just to pass this data off.
I have an AppSync GraphQL API set up with the following (simplified) schema:
type Mutation #aws_api_key
#aws_cognito_user_pools {
sendSearchResults(input: SearchResultInputHeader!): SearchResultOutputHeader
}
input SearchResultInput {
assetId: String
score: Float
}
input SearchResultInputHeader {
callId: String
results: [SearchResultInput]
}
type SearchResultOutput #aws_api_key
#aws_cognito_user_pools {
assetId: String
score: Float
}
type SearchResultOutputHeader #aws_api_key
#aws_cognito_user_pools {
callId: String
results: [SearchResultOutput]
}
and the following request / response resolver mappings:
// REQUEST::
{
"version": "2017-02-28",
"payload": {
"callId": "${context.arguments.input.callId}",
"results": "${context.arguments.input.results}"
}
}
// RESPONSE::
$util.toJson($context.result)
I am able to pass the callId String through this mutation but I am unable to get the results to pass through
// INPUT::
mutation MyMutation {
sendSearchResults(input: {resultsIn: [{assetId: "0001", score: 10}, {assetId: "0002", score: 22}], callId: "aaa-aaa-aaa"}) {
callId
resultsOut {
assetId
}
}
}
// RETURN::
{
"data": {
"sendSearchResults": {
"callId": "aaa-aaa-aaa",
"resultsOut": null
}
}
}
So I have two main questions:
How can I get the resolver/mutation to return a list of results rather than null?
Any other suggestions on passing data through an AppSync mutation and subscription? Or does this approach seem to make sense without writing to a database and just receiving a key?
Thanks!
// REQUEST::
{
"version": "2017-02-28",
"payload": {
"callId": "${context.arguments.input.callId}",
"results": "${context.arguments.input.results}"
}
}
// INPUT::
mutation MyMutation {
sendSearchResults(input: {resultsIn: [{assetId: "0001", score: 10}, {assetId: "0002", score: 22}], callId: "aaa-aaa-aaa"}) {
callId
resultsOut {
assetId
}
}
}
Here is results and resultsIn are different is two places.
I am trying to update the value of a table using the AWS-app sync graphql API,
I am able to create data and add it in a table using graphql mutation in lambda
but when I am trying to update the data its not working.
I am calling this lambda service from an API Gateway.
I am referring this article to code
https://cloudonaut.io/calling-appsync-graphql-from-lambda/
I would like to mentioned git no error in cloud watch log
Here is the schema for my graphql
type Mutation {
createLib_content(input: CreateLib_contentInput!): lib_content
#aws_iam
updateLib_content(input: UpdateLib_contentInput!): lib_content
#aws_iam
deleteLib_content(input: DeleteLib_contentInput!): lib_content
}
input CreateLib_contentInput {
content: String
userId: String
}
input UpdateLib_contentInput {
content: String
id: ID!
}
Create Mutation
graphqlData = await clientDetails.mutate({
mutation: gql(`
mutation CreateLibContent($input: CreateLib_contentInput!) {
createLib_content(input: $input) {
id
content
}
}`),
variables: {
input: {
content : {},
userId : identitiesDetails.userId
}
},
});
Update Mutation
const mutation = gql(`
mutation UpdateLibContent($input: UpdateLib_contentInput!) {
updateLib_content(input: $input) {
userId
content
}
}`);
await clientDetails.mutate({
mutation,
variables: {
input: {
id : "2947c37e-6f76-40d8-8c10-4cd6190d3597",
content : JSON.stringify(event)
}
}
}).promise;
Thanks to #cppgnlearner your guess were right.
I just removed the .promise from my update code
And it started working.
can't believe such a small thing took my whole day.
We are having huge troubles with subscriptions with arguments
to simplify the problem Here are the steps to reproduce
create a simpleSchema
type Mutation {
testSubMutation(param: String!): String
}
type Query {
testQuery: String
}
type Subscription {
testSubs(param: String): String
#aws_subscribe(mutations: ["testSubMutation"])
}
I attached a local resolver to the mutation which returns the timestamp.
in one window open the app sync query tab and make the subscription
subscription sub{
testSubs
}
in the other window make a mutation
mutation mut{
testSubMutation(param:"123")
}
works like a charm
now change the subscription to listen to a parameter
subscription sub{
testSubs(param:"123")
}
Does not work any more. :(
Any help is appreciated.
Subscriptions require the parameter you're filtering on to be in the response of the mutation. Could you try updating your mutation to this?
mutation mut{
testSubMutation(param:"123") {
param
}
}
I'm doing same as above for subscription but not getting response, It's only working with one argument room
mutation addMessage {
addMessage(input: {
room: "45a87f5b-ef9e-41cd-9cd7-f3e2f4946d31",
receiver: "3cea9c02-1cf5-4248-8ebe-3580a7a47b8b" }) {
id
room
receiver {
id
userName
}
}
}
subscription roomMessage {
roomMessage(room: "45a87f5b-ef9e-41cd-9cd7-f3e2f4946d31",
receiver: "3cea9c02-1cf5-4248-8ebe-3580a7a47b8b") {
id
room
receiver {
id
userName
}
}
}
I'm trying to get to grips with AWS AppSync. I'm quite new to GraphQL. I've got the following GraphQL:
type Mutation {
deleteParcel(geoHash: String!, type_id: String!): Parcel
addParcel(input: ParcelInput!): Parcel
batchAddParcels(parcels: [ParcelInput]): [Parcel]
}
type Parcel {
geoHash: String!
type_id: String!
}
type ParcelConnection {
items: [Parcel]
}
input ParcelInput {
geoHash: String!
type_id: String!
}
input ParcelsInput {
parcels: [ParcelInput]
}
type Query {
getNearbyParcels(geoHash: String!): ParcelConnection
}
type Subscription {
onAddParcel(geoHash: String, type_id: String): Parcel
#aws_subscribe(mutations: ["addParcel"])
onBatchAddParcels(geoHash: String): Parcel
#aws_subscribe(mutations: ["batchAddParcels"])
onDeleteParcel(geoHash: String, type_id: String): Parcel
#aws_subscribe(mutations: ["deleteParcel"])
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
All seems to be setup fine on AWS console. I get the schema.json and then run command:
aws-appsync-codegen generate AWSGraphQL.graphql --schema schema.json --output AppsyncAPI.swift
and get the response:
../SnatchHQ/snatch_appsync/AppSync/AWSGraphQL.graphql: Directive "aws_subscribe" may not be used on FIELD_DEFINITION.
.../SnatchHQ/snatch_appsync/AppSync/AWSGraphQL.graphql: Directive "aws_subscribe" may not be used on FIELD_DEFINITION.
.../SnatchHQ/snatch_appsync/AppSync/AWSGraphQL.graphql: Directive "aws_subscribe" may not be used on FIELD_DEFINITION.
error: Validation of GraphQL query document failed
Can anyone help?
If the file AWSGraphQL.graphql is your API GraphQL schema, then that explains the problem. What you need to do is define a *.graphql file that defines your query, mutation, and subscription operations based on your GraphQL API. For example, the following query definitions would match your schema
mutation AddParcel($geoHash: String!, $type_id: String!) {
addParcel(input: {
geoHash: $geoHash
type_id: $typeId
}) {
...Parcel
}
}
query GetNearbyParcels($geoHash: String!) {
getNearbyParcels(
geoHash: $geoHash
) {
...ParcelConnection
}
}
subscription OnAddParcel {
onAddParcel {
...Parcel
}
}
fragment Parcel on Parcel {
geoHash
type_id
}
fragment ParcelConnection on Parcel Connection {
items {
...Parcel
}
}
Assuming you named it something like parcels.graphql, you can then call the following to generate a Swift implementation of the AddParcel mutation, the GetNearbyParcels query, and the OnAddParcel subscription
aws-appsync-codegen generate parcels.graphql \
--schema schema.json \
--output AppSyncParcelsAPI.swift