Support Firestore sub-collections
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/*/authorswork 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 :smile:
@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 😄
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 :wink: )
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?
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.
@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.
@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.