codegen currently involves importing the schema from the user's app. Depending on the structure of the app, that could be a very expensive operation (in my case, this pulls in our ORM and a number of other dependencies). In my current application with only 5 or 6 queries, this is currently taking about 19s to generate all the output files. If I only import the schema once and run the generator on all the queries in the same process, this time drops to about 4s.
I propose a couple minor changes to the strawberry codegen
CLI (and underlying user-facing APIs). First, I propose we add nargs=-1
to the query CLI argument. This will allow multiple queries to be passed on the command line.
The existing plugins use a hardcoded output file name. e.g. types.py
or types.js
. Changing this would likely be problematic because scripts might assume this is the output file and move it to a different name per query. Because of this, the builtin plugins do not support processing multiple query files without some additional shenanigans. There are two ways we could handle this:
types.py
/types.js
. If there are more than one query passed, use the query.stem + extension
(where extension would vary by plugin).I have a branch downstream where I implemented the second, but implementing the first would be relatively simple as well.
Generally, to make this work, I have adjusted the QueryCodegenPlugin
to accept a file path in it's __init__
. It's unlikely that people are overriding this currently, but if they are, we can try
/except
the TypeError
and slap the query
property on the class after initializing it but before doing anything else with it. This should solve most backward compatibility issues (we'd only have problems if they call __init__
directly with no arguments -- e.g. from super().__init__()
and ever that could be alleviated by having a default value that could be sniffed out (e.g. Path.home()
-- it doesn't make sense to have a query's filename be a directory).
A potentially simpler alternative is we could just keep everything with a no-args __init__
and always just add the query
property in a loop after we've constructed all the user-space plugins. From the perspective of the exposed API, the query
filename will always be present and not None
. This probably requires a little white lie to the type-system for a very shot period, but in my experience, mypy
is willing to believe a class has the properties that you claim in spite of what __init__
does.
A proof of concept implementation is at main...mgilson:strawberry:multiple-codegen
but this could easily be tweaked in any of the ways listed above very easily.
Thoughts?
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too