Unknown directive "connection" -- AWS Appsync graphql [duplicate] - amazon-web-services

I am currently developing an eCommerce App in React Native Expo that utilizes AWS amplify and I am trying to connect the API and database to it.
After running 'amplify push', I get the following error message:
� An error occurred during the push operation: Unknown directive 'connection'. Either remove the directive from the schema or add a transformer to handle it.
For some reason, it doesn't recognize #connection as its own directive.
The block of code in the schema.graphql that utilizes this directive is the following:
type CartProduct #model #auth(rules: [{allow: public}]){
id: ID!
userSub: String!
quantity: Int!
option: String
productID: ID!
product: Product #connection(fields: ["productID"])
}
I haven't found a solution anywhere and I appreciate anyone who can help me with this.

This github issue in the aws-amplify repo helped me solve a similar error. The gist of the problem is the graphql transformer version that interprets the schema definition was upgraded to v2 and the #key and #connection directives are in a version 1 directives.
For version 2 I used #hasMany and #hasOne directives.
type PurchaseOrder #model #auth(rules: [{ allow: owner }]) {
id: ID!
poNumber: String
dateOrdered: AWSDateTime
dateRequested: AWSDateTime
dateReceived: AWSDateTime
notes: String
subtotal: Float
taxRate: Float
salesTax: Float
priceAdjustment: Float
discount: Float
total: Float
requestor: String
paymentTerms: String
shipping: Float
comments: String
billingAddress: Address #hasOne
shippingAddress: Address #hasOne
shippingInformation: String
customerId: String
createdAt: AWSDateTime!
updatedAt: AWSDateTime!
poItems: [PoItem] #hasMany
attachments: [Attachment] #hasMany
vendorID: ID!
vendor: Vendor #hasOne
}

Related

AWS AppSync GraphQL one to many relation connection

I am using AWS Appsync with dynamoDB and trying to create a connection between two schema Course and Badges in which once course can have multiple badges list. While badges list are static (don't change it frequently). I tried this but it doesn't worked.
type Badge #model #auth(rules: [{allow: private}]) {
id: ID!
Name: String
}
type Course #model #auth(rules: [{allow: private}]) {
id: ID!
badges: [Badge] #connection
}
You can find the solution here as for the documentation.
Please make sure that you don't read the legacy docs, as #connection directive is deprecated.
Hope it helps!

Apollo Federation (Gateway): how to send different "keys" to different implementing microservices?

I am trying to compose a federated apollo service with a gateway and 3 implementing microservices.
MS1:
type Movie #key(fields: "id name") {
id: String!
name: String
}
MS2:
type Location #key(fields: "id") {
id: String!
longitude: Float!
latitude: Float!
}
type Movie #key(fields: "id") #extends {
id: String! #external
location: Location
}
MS3:
type Award #key(fields: "name"){
name: String!
count: Int
}
type Movie #key(fields: "name") #extends {
name: String! #external
award: Award
}
MS1 provides a name and an id.
name shall be send to MS3 for the resolving process and id shall be used by MS2 for the resolving process.
This approach worked with an older version of apollo-gateway / apollo-server, but with the latest versions I receive the following error messages.
{"stack":"Error: A valid schema couldn't be composed. The following composition errors were found:\n\t[ms2] Movie -> extends from ms1 but specifies an invalid #key directive. Valid #key directives are specified by the originating type. Available #key directives for this type are:\n\t#key(fields: \"id name\")\n ...}
An approach to provide the keys like this didn't work either:
type Movie #key(fields: "id") #key(fields: "name") {
What does the schema have to look like to provide the described use case?

AppSync - unable to create a schema with an array when the array property has `#key` directive associated with it

I recently added a #key directive to a schema field so that I could search by that field, although I now get an error implying the previously correct data type is not what is expected. It says it expects a string but got a list, although the field is a list containing an enum.
Is it possible to query by a specific field without using #key? If not, how can I create records when the #key (seemingly) changes the expected type of a list to a string?
Below is my code, I added the #key to the categories list, but now when I try to create a new Journey I get the error shown below.
This is the schema:
type Journey #model
#auth(rules: [{ allow: owner, operations: [create, delete, update] }])
#key(name: "getJourneysByCategories", fields: ["categories"], queryField: "getJourneysByCategories")
#key(name: "getJourneysByName", fields: ["name"], queryField: "getJourneysByName") {
id: ID!
name: String!
description: String
coverImage: String
isPrivate: Boolean!
members: [JourneyUsersBridge] #connection(name: "JourneyUsers")
moderators: [JourneyModeratorsBridge] #connection(name: "ModeratedBy")
creator: User! #connection(name: "JourneyCreator")
goals: [Goal] #connection(name: "JourneyGoals")
posts: [Post] #connection(name: "JourneyPosts")
categories: [JourneyCategory!]!
}
This is an example of the code used to create a Journey:
type CreateJourneyInput = {
name: string;
description?: string | null;
coverImage?: string | null;
isPrivate: boolean;
categories: Array<JourneyCategory | null>;
journeyCreatorId: string;
};
const journey: CreateJourneyInput = {
name: 'My GraphQL Journey',
description: 'This Journey was made using GraphQL minus DataStore!',
isPrivate: false,
categories: [JourneyCategory.EXMAMPLE],
journeyCreatorId: userId
};
const result = await API.graphql(
graphqlOperation(mutations.createJourney, { input: journey })
);
This is the full error:
"One or more parameter values were invalid: Type mismatch for Index Key categories Expected: S Actual: L IndexName: getJourneysByCategories (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: U4EB7HPO1GU5LHVAOPMGAJJHANVV4KQNSO5AEMVJF66Q9ASUAAJG)"
So I removed the getJourneysByCategories key and the upload worked fine. What's happening here and why?
I just want to be able to query by categories - perhaps #key wasn't the right route to take? Does the key directive not work with lists?

User connection to another User as a friend relationship - AWS GraphQL Transform

I'm using AWS GraphQL Transform to build my schema, and I can't find any resources that point me to how I make a connection between one user and another without creating another type object.
type User #model)
{
id: ID!
email: String!
password: String!
friends: [User] #connection(name: "UserFriendConn")
blockedUsers: [User] #connection(name: "UserBlockedConn")
friendRequests: [User] #connection(name: "UserFriendRequestConn")
}
Calling amplify api gql-compile will throw error: InvalidDirectiveError: Found one half of connection "UserFriendConn" at User.friends but no related field on type User.
Am I applying an entirely wrong pattern here?
This is what your connections should look like. Given that your other types are:
Friend
BlockedUser
FriendRequest
type User #model) {
id: ID!
email: String!
password: String!
friends: [Friend] #connection(name: "UserFriendConn")
blockedUsers: [BlockedUser] #connection(name: "UserBlockedConn")
friendRequests: [FriendRequest] #connection(name: "UserFriendRequestConn")
}

AWS Amplify not generating proper graphql input depth

I am new to both graphql & AWS Amplify, so please forgive any ignorance :)
I have a graphql schema like this:
type Location #model #auth(rules: [{allow: owner}]){
street: String
city: String
state: String
zip: String
}
type Trip #model #auth(rules: [{allow: owner}]){
id: String!
...
location: Location
}
I'm trying to create both the location and the trip at the same time with a mutation request like this:
mutation {
createTrip(input: {
id: "someIdentifier",
location: {
street: "somewhere"
}
}) {
id
location {
street
}
}
}
But I'm getting an error like this:
{
"data": null,
"errors": [
{
"path": null,
"locations": [
{
"line": 2,
"column": 21,
"sourceName": null
}
],
"message": "Validation error of type WrongType: argument 'input' with value '...' contains a field not in 'CreateTripInput': 'location' # 'createTrip'"
}
]
}
Checking the generated schema.graphql file, I see that there is indeed no location object on the input model:
input CreateTripInput {
id: String!
...
}
How can I have amplify generate the proper input schema so that I can create both the Trip and the location objects at the same time?
I was able to get an answer from the aws-amplify team here. To summarize:
Both Trip and Location have model directive. There isn't a #connection directive connecting the Trip with Location. The two options to "resolving" this is:
Update the schema connecting the models if you want them to be in 2 separate tables and want the ability to query Trip based on Location. Using 2 separate table you won't be able to create both Trip and Location in a single mutation, though. For example:
type Location #model #auth(rules: [{allow: owner}]){
street: String
city: String
state: String
zip: String
trips: Trip #connection(name:"TripLocation")
}
type Trip #model #auth(rules: [{allow: owner}]){
id: String!
location: Location #connection(name:"TripLocation")
}
The second option, if the Location data is very specific to a trip and you don't want to create a separate table, then get rid of #model directive from your Location type. Doing so would allow you to create Location as a part of same mutation.
type Location {
street: String
city: String
state: String
zip: String
}
type Trip #model #auth(rules: [{allow: owner}]){
id: String!
location: Location
}
The later was the solution that I moved forward with.