Parse partial source by delegating calls to the internal parseX methods of the Parser#501
Parse partial source by delegating calls to the internal parseX methods of the Parser#501vladar merged 6 commits intowebonyx:masterfrom spawnia:partial-parsing
Conversation
|
For me, it seems equivalent to just making those parser methods public. Not sure if I am happy exposing those implementation details. Technically we can do this since those methods will always be a part of the parser (at least as long as there are corresponding AST nodes). It is unlikely to cause any breaks in the future. But still, it significantly increases the API surface comparing to a single unified Can you elaborate a bit on the motivation behind this change? Do you have performance/memory issues because of this or is it just inconvenience? |
The API of the parser methods is actually wildly different, they neither take or return any arguments. The As long as the AST or GraphQL itself do not change, i think those helpers should be pretty stable. The interface is simple enough: Pass a string and get an AST. At the moment, i am utilizing the fact that the internal implementation lines up perfectly consistent with what an ideal public API would look like. If internals were to change, we could always rewrite the mapping between the public helpers and the new internals.
I think the schema first approach is a nice way to develop a GraphQL server. We require the AST for some functionality in Lighthouse, mainly server side directives. Sometimes, it is necessary to parse just some bits of SDL, for example when adding to the schema programmatically or allowing some extension points within predefined schematas for the user to fill in. We have not suffered a large performance/memory penalty, but we do have to maintain our own partial parser, see https://github.com/nuwave/lighthouse/blob/master/src/Schema/AST/PartialParser.php. The example in the initial description honestly seems like a huge hack for something that could be quite simple. |
|
OK, let's go this route. Do you have anything to add in this PR?
Just curious are you doing this for convenience/readability (comparing to manual AST building)? |
|
It will need PHPStan ignore error rule to be added for Parser |
|
@spawnia @vladar instead of putting this on top of Sorry I'm bad with naming, but e.g. |
|
@simPod Yeah, I forgot that dynamic methods are disabled in PHPStan, thanks for reminding! %) |
The coupling between this seperate class and the Parser would be extremely tight, so i do not see a benefit of splitting them up.
Then we would also have to expose the internal functions that deal with the lexer. At that point, we lose any encapsulation and make it impossible to change the implementation of the Parser without breaking users.
That would force anyone else to setup this helper and repeat typing out the 58 parseX method's signatures to get proper autocompletion. I just added the rest of the helpers, as i still think this solution is the best compromise both in maintainability and usability.
That is the main reason, yes. Manually building even the AST is extremely verbose. IDE support for authoring SDL is quite nice as well, so it is quite easy to get it correct as well. For our particular use case, we really need the SDL as we utilize schema directives as the primary reusable building block. Since they are only a part of the SDL and do not map to executable types, we have to work at this level. |
|
Btw i renamed a few of the internal methods such as I do understand the intent behind their original naming though, it made sense in its own way and i am open to reverting this renaming. @vladar this one is up to you. |
|
@vladar this one is ready to go. I reverted the unnecessary renamings but changed two of the |
We use partial parsing extensively within Lighthouse, a schema first GraphQL server for Laravel.
It has been quite cumbersome to implement, e.g. this is what has to be done in order to parse an input value definition:
With the new API i am proposing, we will be able to just call the Parser directly:
I implemented this via the magic
__callStaticmethod on theParserclass to take advantage of the existing privateparseXmethods.Because of the way the Parser and the Lexer interact, writing out the individual methods statically would result in a lot of boilerplate, which is why i went for the magic method style. The PHPDoc annotations should provide near equivalent IDE help and static analysis safety.
What do you think of that implementation?