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
finds
andgets
operations to plurial style could be more easy to use - Rename the old
objectId
toid
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.