Skip to content
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

Consider exporting parser helpers again in 0.4.3+ #168

Closed
nemanja-stanarevic opened this issue Sep 2, 2015 · 3 comments
Closed

Consider exporting parser helpers again in 0.4.3+ #168

nemanja-stanarevic opened this issue Sep 2, 2015 · 3 comments

Comments

@nemanja-stanarevic
Copy link
Contributor

With consolidation of schema parser into the main language parser, a number of types and functions that were perviously exported from parserCore to support parseSchemaIntoAST (e.g. makeParser, peek, skip, loc, any, many, etc.) are no longer exported.

This is unfortunate, because all these functions are very helpful for building custom GraphQL schema pre-processors. Pre-processors could be very handy. For example, we built a preprocessor with < 0.4.2 that removes a lot of boilerplate from Relay mutation definitions. No longer doable in 0.4.3 without forking a parser.

I am happy to pull together a PR with updated function declarations if y'all agree it makes sense to export helper functions, as was the case prior to 0.4.3.

@gyzerok
Copy link

gyzerok commented Sep 3, 2015

@nemanja-stanarevic can you share your preprocessor for Relay?

@leebyron
Copy link
Contributor

leebyron commented Sep 3, 2015

It would be helpful to know more about what you're trying to do to see what kind of direct support the library can provide. The parserCore file was an implementation detail and not intended to be imported from third-party code.

@nemanja-stanarevic
Copy link
Contributor Author

We are doing some AST manipulation to shorthand some common schema definition patterns. For example, a Relay mutation definition goes something along these lines:

type Mutations {
  addFoo(input: AddFooInput!): AddFooPayload
  deleteFoo(input: DeleteFooInput!): DeleteFooPayload
}
input AddFooInput {
  id: ID
  name: String
  clientMutationId: String!
}
type AddFooPayload {
  newFoo: Foo
  viewer: Viewer
  clientMutationId: String!
}
type DeleteFooInput {
  id: ID
  clientMutationId: String!
}
type DeleteFooPayload {
  deleteFooId: ID
  viewer: Viewer
  clientMutationId: String!
}

Instead of all that, we have -

define mutation addFoo(id: ID, name: String) {
  newFoo: Foo
  viewer: Viewer
}
define mutation deleteFoo(id: ID) {
  deleteFooId: ID
  viewer: Viewer
}

We essentially make mutation definitions first class citizens in the schema definition language (not too crazy about define token there, but it makes for easier disambiguation from mutation operation without peeking too much ahead).

This DSL goes through a custom parser (really just GraphQL parser + ~20 loc) that produces an AST with a custom node of MutationFieldDefinition kind. Then, a pre-processor uses AST visitor to pluck all mutation field definition nodes and stick them as fields of Mutations type, defines all ...Input input objects and ...Payload types per Relay specs, etc. This gets us to an AST with all the standard nodes that can safely go through validation and schema materializer.

We actually had a custom parser in place for schema DSL, but dropped it in favor of GraphQL schema parser when it was released in July. Bottom line is that you have a really nice, clean, hackable parser in there and it may be helpful to expose some building blocks for people developing DSLs. I see this mainly happening on the schema definition side of the language, not so much on the core operations. On the other hand, keeping API surface small is better. It's really not a big deal for our use case either way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants