You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I quite like the idea of defining schemas simply as strings – it's great that it can be a part of the git repo in such a form. This makes the schema readable by any member of the team without running a server and also enables the new features to be tracked even by those who is not great in server-side JS (git diff for a spec looks pretty straightforward).
A problem being introduced by this approach is that some parts of the schema become a bit more verbose than needed, e.g. when some set of fields is shared between an interface and derived types:
When I wrote my first schema in a text form, I intuitively expected this to work:
exportdefault/* GraphQL */`interface Character { id: ID! name: String! friends: [Character] appearsIn: [Episode]!}type Human implements Character { starships: [Starship] totalCredits: Int}type Droid implements Character { primaryFunction: String}`;
As probably guessed, this was not very successful :–) BTW /* GraphQL */ just helped Atom's language-babel plugin nicely highlight the types.
On the yesterday's GraphQL meetup in London I shortly discussed this problem of self-repetition with @martijnwalraven and he explained me why it cannot be solved with the concept fragments. Turns out fragments are designed to be used only on the client and their main purpose is not to reduce the number of the lines of code, but to perform some cool magic.
However, I still think that there's something that may be done in the server-side app to avoid too much repetition. It does not necessary have to be a part of the GraphQL spec – just some basic ‘syntax sugar’ will do the job (our purpose is just to make the schema definition readable by everyone including product managers).
The first thing that comes to mind is some form of a ES6 spread operator (which implements a simple string.replace() under the hood). A quick sketch:
importwithSchemaMixinfrom'graphql-tools/with-schema-mixin';constwithCharacterFields=withSchemaMixin('characterFields',/* GraphQLMixin */` id: ID! name: String! friends: [Character] appearsIn: [Episode]!`);exportdefaultwithCharacterFields/* GraphQLWithMixins */`interface Character { ...characterFields}type Human implements Character { ...characterFields starships: [Starship] totalCredits: Int}type Droid implements Character { ...characterFields primaryFunction: String}`;
This may work not just for the sets of fields, but also for certain collections of commonly used attributes. Mixins (or whatever this thing may be called) can be easily made composable.
Thinking further, these mixins may be made smarter than just bare-bone string.replace() and even work as true spread operators. In type Customername would turn from a locale-aware filed to a normal one. But that's probably a bit too hard conceptually for a start.
Although I see certain benefits in this extra layer of abstraction, I understand that it comes at a cost, which is first of all the existence of the layer of abstraction as such. Besides, with the introduction of these mixins in the schema definition file, the resolvers might need to get something similar as well.
However, at the moment I see more pros than cons in the overall idea, especially in the long run. As the GraphQL tooling improves further, server developers will probably get more focused on the schema than on the underlying layer with resolvers, so keeping things shorter and thus more human-readable can help many teams.
I'm curious to know what the community thinks of this extra ‘syntax-sugar’ idea for Apollo's graphql-server. Feel free to criticize it as much as you want – it's pretty raw after all! :–)
The text was updated successfully, but these errors were encountered:
I quite like the idea of defining schemas simply as strings – it's great that it can be a part of the git repo in such a form. This makes the schema readable by any member of the team without running a server and also enables the new features to be tracked even by those who is not great in server-side JS (
git diff
for a spec looks pretty straightforward).A problem being introduced by this approach is that some parts of the schema become a bit more verbose than needed, e.g. when some set of fields is shared between an interface and derived types:
When I wrote my first schema in a text form, I intuitively expected this to work:
As probably guessed, this was not very successful :–) BTW
/* GraphQL */
just helped Atom'slanguage-babel
plugin nicely highlight the types.On the yesterday's GraphQL meetup in London I shortly discussed this problem of self-repetition with @martijnwalraven and he explained me why it cannot be solved with the concept fragments. Turns out fragments are designed to be used only on the client and their main purpose is not to reduce the number of the lines of code, but to perform some cool magic.
However, I still think that there's something that may be done in the server-side app to avoid too much repetition. It does not necessary have to be a part of the GraphQL spec – just some basic ‘syntax sugar’ will do the job (our purpose is just to make the schema definition readable by everyone including product managers).
The first thing that comes to mind is some form of a ES6 spread operator (which implements a simple
string.replace()
under the hood). A quick sketch:This may work not just for the sets of fields, but also for certain collections of commonly used attributes. Mixins (or whatever this thing may be called) can be easily made composable.
Thinking further, these mixins may be made smarter than just bare-bone
string.replace()
and even work as true spread operators. In typeCustomer
name
would turn from a locale-aware filed to a normal one. But that's probably a bit too hard conceptually for a start.Although I see certain benefits in this extra layer of abstraction, I understand that it comes at a cost, which is first of all the existence of the layer of abstraction as such. Besides, with the introduction of these mixins in the schema definition file, the resolvers might need to get something similar as well.
However, at the moment I see more pros than cons in the overall idea, especially in the long run. As the GraphQL tooling improves further, server developers will probably get more focused on the schema than on the underlying layer with resolvers, so keeping things shorter and thus more human-readable can help many teams.
I'm curious to know what the community thinks of this extra ‘syntax-sugar’ idea for Apollo's
graphql-server
. Feel free to criticize it as much as you want – it's pretty raw after all! :–)The text was updated successfully, but these errors were encountered: