-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Feedback/Discussion: GraphQL Spec #5863
Comments
@Moumouls thanks for the detailed feedback. All the ideas you sent are really helpful. I will comment each of them and I'd love to discuss them further with you and all others, including @douglasmuraoka and @omairvaiyani We've managed the GraphQL ideas in this project and any help on tackling them is very welcome! Would you be willed to help us on this challenge? 🍻 Here it goes my comments: Relay SpecIt makes totally sense. I've just created a new task of this. Quick question: I personally think the current types are much easier to be used (except if you are using Relay) than the Relay spec; do you think that we should in someway keep both options or just replace everything? Where operator mapI really needed to have some char (in the case I used the Return Type on MutationsSo you proposed to return all columns instead of only the modified ones (as in the REST API). Right? I think it makes sense as well and I've just created this new task. Data OrganizationI agree with your suggestions, but the data was organized like this to avoid name collision. Commenting each of your suggestions:
SecurityI had already noticed and created a task for this. It will be addressed very soon. Again, thank you so much for your feedback. Let's keep this discussion live and address each of your ideas. If you also have anything else in your mind, just let me know. |
@davimacedo yes i think i can help in the Relay SpecDuplication of structure will lead to confusion for new developers, i'm not sure it's a good idea. I agree that Where operator mapYou are right, for a better understanding we can add documentation in the Return Type on MutationsYes when we use create/update/delete(important) Data OrganizationSo the naming For plurial naming, most of developers take care about naming, having a |
@Moumouls thanks for your help! Feel free to grab any of the tasks to start working on.
|
@davimacedo I can dive into the `GraphQL Server', but I can't move any tasks in the project..... About data organization, I think that I'm totally in favor of leaving the old code/strategy to implement a better `GraphQL Server', we have the ability to easily notify the developer during generation if we detect a strange data structure/name ! After a new short analysis of the current
|
That's nice! Let's start working on this! I think it is important to tackle the ideas in small PRs instead of a single PR with everything so we can work in parallel. Which task do you want to first start with? I will start working on Relay compliance, ok? |
I can begin a PR and take the |
Nice! Send a PR with the suggestions you have for the new names and we can discuss there. If you have any question about the code, let me know. I've just added this new task to the project. Let's keep this issue open so we can keep tracking/addressing all other ideas. |
@Moumouls I did a deep analysis of the Relay spec and also checked out some benchmarks. The current API is actually much easier to use than the Relay spec. As a developer I'd prefer to use the current one for non Relay projects or when playing using Playground. On the other hand, it is very important to be Relay compliant and I saw that one of the benchmarks (Hasura) is not compliant and there is an issue with a lot of people asking them to include the compliance. It will probably happen the same thing here if we do not develop it now. So I started asked myself again which would be the best option:
Thoughts? I'd love to hear other thoughts as well. @omairvaiyani @douglasmuraoka @TomWFox @acinader @dplewis @alencarlucas Anyway I started writing the code we will need to be compliant. |
As a GraphQL developper i will vote for the option 3. I already worked with a I think we have a lot of reflexion about the implementation here, i suggest to define the |
Being upfront, I've not used Relay as our company's product is built entirely on Ember.js, so I understand my bias here. As it stands, there are no officially supported libraries for the Relay client on Angular, Vue, Ember.js or even React-native (though I might be misinformed on that last one). Having said that, Relay does have almost as many Github stars as GraphQL.js, suggesting that there's a high overlap between those who use GraphQL, and those who also use Relay. So I do understand the need for spec compliance. @davimacedo Out of your 3 options, I think we can alter Option 1 and pour some effort into maintaining both. Much of the suggestions outlined by @Moumouls above are items that will not result in poorer experience on non-Relay projects. We could have a base where most of the spec is Relay compliant, such as naming conventions, but when switched on to Relay, differs in the strict return types and pagination architecture. In this approach, I think from an instance perspective, the resultant schema either be one or the other, but not both as that would lead to confusion. It may also be worth considering an addon approach for simpler code maintenance, for example: const parseGraphQLServer = new ParseGraphQLServer(options);
parseGraphQLServer.use(new ParseRelayAddon()); Should we opt for Option 3 instead and only support Relay - it's worth considering whether the Parse SDK's can expose APIs to simplify access to their Parse GraphQL server. |
Also +1 on setting the |
I believe the current GraphQL API brings a lot to Parse users, whether GraphQL expert or not. And although we may need to change the current schema to be Relay compliant, both schemas are not necessarily exclusive. It will demand more effort to keep up with both APIs, but I think this is the right way for Parse. I'll vote for option 1. Additionally, I also agree with @Moumouls that It may cause some confusion between users. So I believe we must also discuss how to make it crystal clear for both Relay and non-Relay users, and those who are not so familiar with GraphQL. |
Nice. So I am going with option 1. I will try to make the two APIs (simple and relay) as close as possible (so we don't have so much duplicated code to maintain) and have a switch flag in ParseGraphQLServer to opt in for a Relay style. I will send a PR soon. I will also add the beta note in the GraphQL section. |
@davimacedo I think my next PR will be on the new # You can send an objectId or a Parse Pointer
input RelationInput {
objectId: ID
pointer: ARelationPointer
}
input ExampleRelationInput {
add: [RelationInput!]
remove: [RelationInput!]
} What do you think about this ? |
I think it is little bit confusing make the two options available in the same input. At a first glance, I'd try to fill both if I were the developer. I think we could go only with the id option. But it would be really good here to also give the option of creating a new object (nested mutation). Maybe the following? input ExampleRelationInput {
add: [ID!]
createAndAdd: [AClassCreateInput!]
remove: [ID!]
} |
I think the way I suggested it is not so good because it is not self explainable for the developer that we are expecting an array of ids, right? So maybe the following would be better? input RelationInput {
objectId: ID!
}
input ExampleRelationInput {
add: [RelationInput!]
createAndAdd: [AClassCreateInput!]
remove: [RelationInput!]
} |
@Moumouls you will probably have a hard time to transform these guys from GraphQL schema to Parse schema. That's why I used |
Proposal for ACLinput UserACLInput {
userId: ID!
# If the value is true, the user can read the current object
read: Boolean
# If the value is true, the user can write on the current object
write: Boolean
}
input RoleACLInput {
roleName: String!
# If the value is true, users who are members of the role can read the current object
read: Boolean
# If the value is true, users who are members of the role can write on the current object
write: Boolean
}
input PublicACLInput {
# If the value is true, anyone can read the current object
read: Boolean
# If the value is true, anyone can write on the current object
write: Boolean
}
input ACLInput {
# Access control level for users
users: [UserACLInput!]
# Access control level for roles
roles: [RoleACLInput!]
# Public access control level
public: PublicACLInput
}
type UserACL {
userId: ID
# If the value is true, the user can read the current object
read: Boolean
# If the value is true, the user can write on the current object
write: Boolean
}
type RoleACL {
roleName: String
# If the value is true, users who are members of the role can read the current object
read: Boolean
# If the value is true, users who are members of the role can write on the current object
write: Boolean
}
type PublicACL {
# If the value is true, anyone can read the current object
read: Boolean
# If the value is true, anyone can write on the current object
write: Boolean
}
type ACL {
# Access control level for users
users: [UserACL]
# Access control level for roles
roles: [RoleACL]
# Public access control level
public: PublicACL
} |
It looks good to me. I would just do few changes regarding required fields: type UserACL {
userId: ID! # <--- Here
# If the value is true, the user can read the current object
read: Boolean
# If the value is true, the user can write on the current object
write: Boolean
}
type RoleACL {
roleName: String! # <--- Here
# If the value is true, users who are members of the role can read the current object
read: Boolean
# If the value is true, users who are members of the role can write on the current object
write: Boolean
}
type PublicACL {
# If the value is true, anyone can read the current object
read: Boolean
# If the value is true, anyone can write on the current object
write: Boolean
}
type ACL {
# Access control level for users
users: [UserACL!] # <--- Here
# Access control level for roles
roles: [RoleACL!] # <--- Here
# Public access control level
public: PublicACL
} |
@Moumouls I think that, in addition to the PRs that are already on going, we are only missing to complete the Relay Spec, right? |
Feedback/Discussion on the
GraphQL
implementationHi, first of all, thanks to all contributors for the awesome work on the
GraphQL
implementationI tested some features and i made a small comparaison between
GraphQL Parse Server
and another solution i lovePrima X Nexus
(alias GraphCool), NexusI'm here to give some feedback and help in the future of the brand new
GraphQL
(huge) feature!Switch Results to Relay Style spec (Connection)
It could be really cool to have
Relay Style
type results instead of the currentresults
structure, it can accelerate global development for migration (from other backends) and front end developers working with Relay specifications for their components.The tricky part, I think, is the
cursor
field.Where Operator Mapping
The
where
input is currently well implemented (better thanPrisma
, where all constraints are at same level ex:createadAt_gt, name_contains
... bad when you have a lot offields
).I think the DX (
Developer Experience
) can be improved with a simple operator inspired by theJS SDK
like:Return types on Mutation
With the current implementation of creation/update developers cannot easly use a front-end cache system. A typed object creation/update (ex:
createRole
) must return the associated type (ex:Role
).Data organization
I think it may be interesting to refactor the data architecture
Here some feedbacks:
objects
,users
,files
(with acreateFile()
).finds
andgets
operations to plurial style could be more easy to useobjectId
toid
A renaming of native endpoints
_Role
and_User
toUser
andRole
will add more consistency (ex:createUser
)Security
In
UserClass
i see that thepassword
is retrieved (not plain i agree) but it could be a huge security breach.The text was updated successfully, but these errors were encountered: