Generate each query, mutation, fragment and scalar type in a separate file.
We use Apollo in production on a pretty large project.
Right now our generated API.swift file is almost 10 Mb and it has 255,000+ lines of code.
After we create a new query/mutation, the file may be overwritten completely, that it is impossible to understand anything in git.
Moreover, Xcode freezes for about a minute when we try to open that single file.
| Code | Git mess |
| :--: | :--: |
|
|
|
As far as all requests and types are public classes, it shouldn't be hard to put each of them in a separate file.
All those files can also be sorted in folders to make it much easier to navigate through the API.
API ->
--Scalars ->
----Upload.swift
--Fragments ->
----UserFragment.swift
--Queries ->
----UserQuery.swift ->
--Mutations ->
----CreateUserMutation.swift
If you provide a folder path instead of a file path to the generate command, it will do exactly this: a separate file for everything.
@TizianoCoroneo
Could you share an example, please?
This is the script as is in the docs:
"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile="schema.json" API.swift
If you make a folder named API just next to your API.swift file, and then remove the .swift extension from the last argument of the script, it should work:
"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile="schema.json" API/
I'm using Swift scripting to generate API from this doc:
ApolloCodegen.run(
from: queriesURL,
with: apolloCLIURL,
options: Options.codegen
)
And I couldn't find a way to get rid of that massive file.
Ok. I guess I've managed how to handle that, there's another init that allows you to specify output format:
let operationIDsURL = outputURL
.appendingPathComponent("operationIDs.json")
let schemaURL = outputURL
.appendingPathComponent("schema.json")
ApolloCodegenOptions(
codegenEngine: .default,
operationIDsURL: operationIDsURL,
outputFormat: .multipleFiles(inFolderAtURL: outputURL),
urlToSchemaFile: schemaURL
)
Closing the issue :)
So, I'm noticing we're getting massive differences in file sizes from the generated output depending on if we use the apollo codegen:generate command through the NPM installed CLI vs. the SwiftCodegenLib.
Like... one of our files is almost 20mb from SwiftCodegenLib but 224kb from the NPM CLI.
What could be causing such as massive difference?
I just compared the commands, and it looks like the default mergeInFieldsFromFragmentSpreads: true is the source of the "bloat".
What is the cost/benefit of having that set to true, as it is by default?
I'm very surprised to hear it's causing that big a jump. mergeInFieldsFromFragmentSpreads ensures that fields in spreads (the ...BlahFragment operator) are actually on the returned object. It basically is the difference between calling object.propertyFromFragment and object.fragment.propertyFromFragment on literally everything, which can get REAL old.
@Mordil you've got my email, can you send me before/after of your API.swift so i can validate assumptions?
In our codebase adding the mergeInFieldsFromFragmentSpreads option causes 220k+ lines of code to appear, mostly:
inits for testing purposes)(I have to admit that we overuse fragments, and that's the main culprit.)
Might be interesting to use dynamic member lookup with keypaths to reduce code bloat, so that the enclosing type can refer dynamically to the properties of the enclosed fragment. I guess this road will be explored in the context of the new Swift Codegen though, right?
Yes. Also representing fragments as protocols means that you can have the properties straight on the object without duplication.
Most helpful comment
Ok. I guess I've managed how to handle that, there's another
initthat allows you to specify output format:Closing the issue :)