#✅ - AWS Amplify / GraphQL API authorisation based off ownerField of another table

45 messages · Page 1 of 1 (latest)

cerulean fog
#

AWS Amplify / GraphQL API authorisation based off ownerField of another table

hollow rivet
#

Hey @cerulean fog , you would have to add that logic to the vtl resolver. Was that code accurate in implementing the behavior you wanted?

#

I would expect there to be some issues trying to get a resolver attached to one datasource to be able to query another

#

I'm not great at VTL myself but this did come up not too long ago. From what I remember it basically goes:

  1. Extend the specific resolver
  2. amplify override api to change the dataSource property of the appsyncfunction

there's an issue with some override code as an example and link to the relevant docs on extending resolvers

https://github.com/aws-amplify/amplify-cli/issues/9623#issuecomment-1023528618

#

so there's a Friend table and a Attributes table so far

#

sorry, I'm not sure I understand why wouldn't the manyToMany directive wouldn't work there. The way you said each "friendship has attributes to it" sounds like a graph database where the relationship between two entities is also part of the data model and has its own data

#

storing data on edges vs nodes

#

I think for this to work in an AppSync GraphQL API you would have to create a separate Friendship table that manages the friends + attributes each user has so you'd have something like friendships: [Friendship] rather than friends: [User]

#

and on the Friendship record or however you'd like to call it, you'd store the attributes

#

that's a good question, I've never tried 😅 let me see if that even compiles real quick

#

well, apparently it compiles

#

i tried this

type User @model {
  id: ID!
  name: String!
  friendships: [Friendship] @hasMany
}

type Friendship @model {
  id: ID!
  user: User @belongsTo
  friend: User @belongsTo
  # ...attribute fields
}
#

you mean in the build schema?

#
type User {
  id: ID!
  name: String!
  friendships(filter: ModelFriendshipFilterInput, sortDirection: ModelSortDirection, limit: Int, nextToken: String): ModelFriendshipConnection
  createdAt: AWSDateTime!
  updatedAt: AWSDateTime!
}

type Friendship {
  id: ID!
  user: User
  friend: User
  createdAt: AWSDateTime!
  updatedAt: AWSDateTime!
  userFriendshipsId: ID
}
#

yeah 🙁

#

local

type User @model {
  id: ID!
  name: String!
  friendships: [Friendship] @hasMany
}

type Friendship @model {
  id: ID!
  userId: ID! @index(name: "byUser")
  user: User! @belongsTo(fields: ["userId"])
  friendId: ID! @index(name: "byFriend")
  friend: User! @belongsTo(fields: ["friendId"])
  # ...attribute fields
}

build

type User {
  id: ID!
  name: String!
  friendships(filter: ModelFriendshipFilterInput, sortDirection: ModelSortDirection, limit: Int, nextToken: String): ModelFriendshipConnection
  createdAt: AWSDateTime!
  updatedAt: AWSDateTime!
  _version: Int!
  _deleted: Boolean
  _lastChangedAt: AWSTimestamp!
}

type Friendship {
  id: ID!
  userId: ID!
  user: User!
  friendId: ID!
  friend: User!
  createdAt: AWSDateTime!
  updatedAt: AWSDateTime!
  _version: Int!
  _deleted: Boolean
  _lastChangedAt: AWSTimestamp!
  userFriendshipsId: ID
}
#

just ignore the userFriendshpsId, I guess lol 🤷‍♂️

#

I'm not 100% sure but I hope so!

#

currently deploying the schema to try it in the AppSync console

#

no problem! and I think we should be okay with just one hasMany directive. The relationship here is only between User and Friendship records

#

to get the friend, you'd have to query it from the Friendship record

#

I don't think so, the two users would share the same friendship record, no?

hollow rivet
#

oh, I see what you mean

#

yeah so you do need two hasMany relationships

#

I don't think AppSync does a cascading delete

#

when you delete a related record, you would get back null on the related record but the id field is probably still populated i imagine

#

don't think so, dynamoDB is not a relational database

#

I haven't messed around with JS resolvers in an Amplify project, I'm not sure that we even support them yet

#

there's an open feature request for it

#

yeah we have to work new features into the Amplify CLI after the services release them

#

yeah, that's understandable

#

I can't work for JS resolvers to be supported, it's going to be so much easier than figuring out VTL. Hopefully soon

#

You could technically add a JS resolver manually in the AppSync console but every time you do amplify push it will be overwritten and you'd have to do it every time

#

unfortunately so

#

most of the advanced use cases require VTL knowledge

#

i'm not sure, but I'm looking into our announcements about them to see if it's mentioned

hollow rivet
#

unfortunately there's no way to batch delete records through the autogenerated mutation + resolvers, you'd have to implement that logic yourself. If you were using datastore that particular thing would be easier because it'd be something like DataStore.delete(Friendship, f => f.userId.eq("<user-id>")))

#

but this is only more convenient from a developer standpoint because it will queue and process a delete mutation for every record that matches the predicate because there's no batch write/update mutation

#

saving you the code of querying for all friendships by foreign key, iterating over the list of friendships and calling the appsync api yourself

hollow rivet
#

DynamoDB does support batch writes, but yeah you gotta get in those resolvers 😭

gentle oreBOT
#

✅ - AWS Amplify / GraphQL API authorisation based off ownerField of another table

#

Answer selected!


1. Extend the specific resolver
2. `amplify override api` to change the dataSource property of the appsyncfunction

there's an issue with some override code as an example and link to the relevant docs on extending resolvers

https://github.com/aws-amplify/amplify-cli/issues/9623#issuecomment-1023528618```
Kudos to @hollow rivet!
#1095753557245964320 message
hollow rivet
#

Nice! would be nice if we generated some plural mutations that mapped to these templates

#

like createTodos or createManyTodos 🤷‍♂️