Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Firestore sub-collections #46

Open
jthegedus opened this issue Jan 28, 2019 · 5 comments
Open

Support Firestore sub-collections #46

jthegedus opened this issue Jan 28, 2019 · 5 comments
Labels
datamodel enhancement New feature or request

Comments

@jthegedus
Copy link

Is your feature request related to a problem? Please describe.
It is unclear at this time how to use firestore subcollections with @gqlify/firestore.

Describe the solution you'd like
I imagine creating the type like so:

type Book @GQLifyModel(dataSource: "firestore", key: "books") {
  id: ID! @unique @autoGen
  title: String!
  author: Author!
}

type Author @GQLifyModel(dataSource: "firestore", key: "books/*/authors") {
  id: ID! @unique @autoGen
  name: String!
}

and then updating or creating a field requires a where params list like so:

type AuthorWhereUniqueInupt {
  bookId: ID!
  authorId: ID!
}

or could we use a Firestore sub-collection specific where param where the id field is the document path? Eg:

type AuthorWhereUniqueInupt {
  parentPath: String!
  authorId: ID!
}

where the parentPath is more like the current path usage in Firestore SDK:

variables = {
  parentPath: `books/${someBookId}`
}

Issues with this solution:

  • how do we query sub-collections?
  • what syntax do we use to represent the document in the collection/document/collection path key? That is, does books/*/authors work well enough?

Describe alternatives you've considered
Using root-level Firestore collections is a viable alternative since relationships/foreign-keys are already supported. There are performance implications with doing so though where sub-collections would be desirable.

Additional context
Just starting a discussion of the idea 😄

@wwwy3y3
Copy link
Contributor

wwwy3y3 commented Jan 29, 2019

@jthegedus Wow!

Thanks for the detailed information!

IMO, in GQLify, @GQLifyModel defines a root level data-model, so maybe we can introduce different directive like GQLifySubResource. It can work for Embedded Documents in MongoDataSource as well.

type Book @GQLifyModel(dataSource: "firestore", key: "books") {
  id: ID! @unique @autoGen
  title: String!
  author: Author! @GQLifySubResource(key: "authors")
}

type Author {
  id: ID! @unique @autoGen
  name: String!
}

GQLifySubResource(key: string)

For firestore, key parameter indicates the name of subcollection. GQLify will know the key should be postfixed after its parent GQLifyModel key and makes it /books/{bookId}/authors/{authorId} if GQLify wants to locates the subcollection document.

GQLify can generate create/update/delete mutations for GQLifySubResource field. For example, createAuthorInBook updateAuthorInBook and deleteAuthorInBook.

As for query, GQLify can generate query like authorInBook to be able to find one author for specified book with bookId and authorId.

Let me know how you think about GQLifySubResource directive 😄

@wwwy3y3 wwwy3y3 added enhancement New feature or request datamodel labels Jan 29, 2019
@jthegedus
Copy link
Author

jthegedus commented Jan 29, 2019

Brilliant idea! Much more flexible across dataSources and therefore useful. I would certainly be happy with this new directive, especially because the association between the two types is more clear, and the type of association is more clear than a "normal" GraphQL type.

Do you foresee any issues with the naming convention of: createAuthorInBook, updateAuthorInBook etc? Deep nesting could get rather messy, do you have any other ideas here? (I haven't thought of anything yet 😉 )

Some more ideas to think about: presumably the SubResource is always contained in the same datasource as the parent type? Would there be a need for otherwise?

@wwwy3y3
Copy link
Contributor

wwwy3y3 commented Jan 30, 2019

Well, regarding the naming convention, I doubt anyone would put subcollection so nested (ex: createAuthorInIssueThreadCommentSubcomment) that it becomes a problem. If it really becomes a problem, we can always add another api to deal with it (ex: createSubResource(path: string, input: Input)) in the future.

As for SubResource data-source, it would be simpler to understand and also implement if we defined it to be contained in the same data-source as the parent type.

@jthegedus
Copy link
Author

@wwwy3y3 I agree completely, just wanted to raise the thoughts.

I think createSubResource(path: string, input: Input) is a great solution should it become a heavily requested feature.

@wwwy3y3
Copy link
Contributor

wwwy3y3 commented Jan 30, 2019

@jthegedus We're always glad to hear thoughts from the community 😄

Please don't hesitate to share your thoughts.

Hope to hear more from you when we release Canner v3 in a few days later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
datamodel enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants