-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Description
Feedback/Discussion on the GraphQL implementation
Hi, first of all, thanks to all contributors for the awesome work on the GraphQL implementation
I tested some features and i made a small comparaison between GraphQL Parse Server and another solution i love Prima X Nexus (alias GraphCool), Nexus
I'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 current results 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.
Query Parameters
after: String,
before: String,
first: Int,
last: Int,
orderBy: ExampleOrderByInput,
skip: Int,
where: ExampleWhereInput
Edge
type UserEdge {
cursor: String!
node: User!
}Connection
type ExampleConnection {
edges: [UserExample!]!
pageInfo: PageInfo!
}PageInfo
type PageInfo {
endCursor: String
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
}Where Operator Mapping
The where input is currently well implemented (better than Prisma, where all constraints are at same level ex: createadAt_gt, name_contains... bad when you have a lot of fields).
I think the DX (Developer Experience) can be improved with a simple operator inspired by the JS SDK like:
const parseMap = {
or: '$or',
and: '$and',
nor: '$nor',
relatedTo: '$relatedTo',
equalTo: '$eq',
notEqualTo: '$ne',
lessThan: '$lt',
lessThanOrEqual: '$lte',
greaterThan: '$gt',
greaterThanOrEqual: '$gte',
contains: '$in',
notContains: '$nin',
exists: '$exists',
select: '$select',
dontSelect: '$dontSelect',
inQuery: '$inQuery',
notInQuery: '$notInQuery',
containedBy: '$containedBy',
containsAll: '$all',
regex: '$regex',
options: '$options',
text: '$text',
search: '$search',
term: '$term',
language: '$language',
caseSensitive: '$caseSensitive',
diacriticSensitive: '$diacriticSensitive',
nearSphere: '$nearSphere',
maxDistance: '$maxDistance',
maxDistanceInRadians: '$maxDistanceInRadians',
maxDistanceInMiles: '$maxDistanceInMiles',
maxDistanceInKilometers: '$maxDistanceInKilometers',
within: '$within',
box: '$box',
geoWithin: '$geoWithin',
polygon: '$polygon',
centerSphere: '$centerSphere',
geoIntersects: '$geoIntersects',
point: '$point',
}; 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:
- Unwrap mutations and queries from
objects,users,files(with acreateFile()). - Rename
findsandgetsoperations to plurial style could be more easy to use - Rename the old
objectIdtoid
Proposition
type Query {
me(...): User!
user(id: ID!): User!
users(...): [UserConnection] or [User]!
role(id: ID!)
exampleObject(id: ID!)
exampleObjects(...): [ExampleObjectConnection]
}
type Mutation {
create(...): CreateResult!
createUser(...): User!
...
}
A renaming of native endpoints _Role and _User to User and Role will add more consistency (ex: createUser)
Security
In UserClass i see that the password is retrieved (not plain i agree) but it could be a huge security breach.