Amplify-js: Filtering queries by relationships

Created on 9 Jan 2019  路  11Comments  路  Source: aws-amplify/amplify-js

* Which Category is your question related to? *
API

* What AWS Services are you utilizing? *
Auth/API

* Provide additional details e.g. code snippets *

I'm building a project management app. I have a top level type known as a Company:

type Company @model @auth(rules: [ { allow: groups, groups: ["SUPERUSER", "ADMIN"], queries: [get, list], mutations: [create, update, delete] }, { allow: groups, groups: ["MANAGER, CONTRACTOR, CONSULTANT"], queries: [get], mutations: null } ] ) { id: ID! title: String! projects: [Project] @connection(name: "CompanyProjects") }

It contains a list of projects, another type:

type Project @model @auth(rules: [ { allow: owner }, { allow: groups, groups: ["SUPERUSER", "ADMIN", "MANAGER"], queries: [get, list], mutations: [create, update] }, { allow: groups, groups: ["CONTRACTOR", "CONSULTANT"], queries: [get, list], mutations: [update] }, ] ) { id: ID! company: Company! @connection(name: "CompanyProjects") createdOn: String! title: String! status: CompletionStatus! description: String documents: [Document] @connection(name: "ProjectDocuments") }

How do I properly use filtering during a query such as listProjects in order to make sure the current user only gets projects related to the company they are a part of?

PS sorry for the code formatting, not sure how to properly do it.

API help wanted pending-close-response-required question

Most helpful comment

I'd also like to know how to filter a query by entity. It seems that Amplify completely ignores the entites and their relation IDs when generating the FilterInput.

In fact, Amplify seems to completely ignore the relation ID everywhere when generating the GraphQL schema; even if you define the entity's type containing the relation field (e.g. projectCompanyId: ID!), it simply doesn't output that field, i.e. neither in the entity's type (e.g. Project) nor in its filters.

All 11 comments

I'd also like to know how to filter a query by entity. It seems that Amplify completely ignores the entites and their relation IDs when generating the FilterInput.

In fact, Amplify seems to completely ignore the relation ID everywhere when generating the GraphQL schema; even if you define the entity's type containing the relation field (e.g. projectCompanyId: ID!), it simply doesn't output that field, i.e. neither in the entity's type (e.g. Project) nor in its filters.

Same... how does this work? It seems like it would be common to be doing something like this, but it doesn't work...

Hey guys! I experienced the same issue. I solved it by exposing the id facilitating the connection, explicitly on the type.

For instance, if you want to filter projects based on the company it belongs to:

type Company @model {
  id: ID!
  name: String!
  projects: [Project] @connection(name: "ProjectCompany")
}
type Project @model {
  id: ID!
  name: String!
  company: Company! @connection(name: "ProjectCompany")
  companyId: ID!

then you can do filtering with:

graphqlOperation(queries.listProjects, {filter: {
  companyId: {eq: <YOUR COMPANY ID>}
}})

NOTE: Its only filtered client side!

Hope this helps!

@MagneH This appears to completely defeat the purpose of having a linked @Connection in the first place. The company in Type Projects @model in my instance... will be null, no matter how many Projects I add, they won't be placed into Company under projects, the @connection to Company, doesn't actually exist, so adding a CompanyId: to make it filterable, is basically ignoring the fact that @connections are entirely 100% broken? None of this makes any sense.

[Project] denotes that it's an array of multiple projects, so I assume that something will exist there when I add them as you would assume to add them... i.e. Add a Company, Add a Project, with a Company ID as 'ProjectCompany' ... kinda works but doesn't.

Ok, it works for me. While you wait for a solution, I am happy with my workaround. 馃@michaelcuneo

This workaround is good but I agree with @michaelcuneo. Why to create @connection at all? We can convert GraphQL to relational database with this workaround.

I had this problem and fixed it with a solution similar to the workaround. It is detailed in the docs (not sure if it was updated after this issue was created here):
https://aws-amplify.github.io/docs/cli/graphql#filtering-by-related-connection-designated-type.

from the docs: "utilizing an auto-generated column from DynamoDB by adding commentTodoId (projectCompanyId for us) to our Comment model". This seems preferable to creating an id field separate from the database's auto-generated column (thanks to @connection)

Following this, the example schema from above becomes:

type Company @model {
  id: ID!
  name: String!
  projects: [Project] @connection(name: "ProjectCompany")
}

type Project @model(subscriptions: null) {
  id: ID!
  name: String!
  company: Company! @connection(name: "ProjectCompany")
  **projectCompanyId: ID!**
}

**type Subscription {
  onCreateProject(projectCompanyId: String): Project @aws_subscribe(mutations: ["createProject"])
  onUpdateProject(id: ID, projectCompanyId: String): Project @aws_subscribe(mutations: ["updateProject"])
  onDeleteProject(id: ID, projectCompanyId: String): Project @aws_subscribe(mutations:["deleteProject"])
}**

This seems to automatically update the "company in Type Projects" to address michaelcuneo's concern. It would still be nice if this were not necessary and if @connection were sufficient to enable relational filtering.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.

@ilrein Do you find a way to solve this issue?

any news?

Was this page helpful?
0 / 5 - 0 ratings