Apollo-ios: Multiple Schema/Hosts In One App

Created on 21 Sep 2018  路  11Comments  路  Source: apollographql/apollo-ios

Is there a common way to use more than one graphql host in the same xcode project? ie, if i have
https://firsthost/graphql
https://secondhost/graphql

Is it possible to import and use both schemas? If so, what is the best practice?

Cheers

feature

Most helpful comment

My solution is similar to @daoseng33 's.

I placed my .graphql files and schema.json corresponding to each endpoints into two different folders.

For example,
SchemaA.json, GraphqlUsingSchemaA_1.graphql, GraphqlUsingSchemaA_2.graphql, ... are put in FolderA.
SchemaB.json, GraphqlUsingSchemaB_1.graphql, GraphqlUsingSchemaB_2.graphql, ... are put in FolderB.

And I modified my Generate Apollo GraphQL API run script into:

APOLLO_FRAMEWORK_PATH="$(eval find $FRAMEWORK_SEARCH_PATHS -name "Apollo.framework" -maxdepth 1)"

if [ -z "$APOLLO_FRAMEWORK_PATH" ]; then
echo "error: Couldn't find Apollo.framework in FRAMEWORK_SEARCH_PATHS; make sure to add the framework to your project."
exit 1
fi

cd "${SRCROOT}/${TARGET_NAME}/FolderA"  //Path to your FolderA
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --schema=SchemaA.json Endpoint_A_API.swift

cd "${SRCROOT}/${TARGET_NAME}/FolderB"  //Path to your FolderB
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --schema=SchemaB.json Endpoint_B_API.swift

Now after I built the project, I go to these folders and drag those API.swift into my project.
That's it.

All 11 comments

This may help Schema stitching

@OrestNazarewycz Did you find any solution to the problem you have mentioned?

Any one can help?
I mean from @victormihaita 's answer, it seems Schema stitching is not something I, as an iOS developer, can do. Not sure.

Is there anything I can do to support multiple graphql endpoints from client side, assuming I can't change any backend codes?

@OrestNazarewycz , you could probably have two different targets within same project/workspace for each graphql endpoint. For example.

FirstHostAPI and SecondHostAPI targets and one schema would go in:

FirstHostAPI/schema.json

while other would be in

SecondHostAPI/schema.json

You would need to maintain one set of graphql files for first host and another one in second host.

I'm facing the same problem, in my case, I want to separate release and debug environment, here's my solution:

  1. Generate both schema-release.json and schema-debug.json, put them in your project top folder
  2. Edit "Generate Apollo GraphQL API" script in Targe Build Phase with below code:
APOLLO_FRAMEWORK_PATH="$(eval find $FRAMEWORK_SEARCH_PATHS -name "Apollo.framework" -maxdepth 1)"

if [ -z "$APOLLO_FRAMEWORK_PATH" ]; then
echo "error: Couldn't find Apollo.framework in FRAMEWORK_SEARCH_PATHS; make sure to add the framework to your project."
exit 1
fi

if [ "${CONFIGURATION}" = "Release" ]; then
cd "${SRCROOT}/${TARGET_NAME}"
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --schema=schema-release.json ReleaseAPI.swift
> DebugAPI.swift
fi

if [ "${CONFIGURATION}" = "Debug" ]; then
cd "${SRCROOT}/${TARGET_NAME}"
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --schema=schema-debug.json DebugAPI.swift
> ReleaseAPI.swift
fi

note: > filename in the script means clear the contents of the file. If now is debug environment then clear releaseAPI content, vice versa. So debug and release content will not be reduplicated, that will cause error in build time

  1. Build the project, and drag DebugAPI.swift & ReleaseAPI.swift to your project

My solution is similar to @daoseng33 's.

I placed my .graphql files and schema.json corresponding to each endpoints into two different folders.

For example,
SchemaA.json, GraphqlUsingSchemaA_1.graphql, GraphqlUsingSchemaA_2.graphql, ... are put in FolderA.
SchemaB.json, GraphqlUsingSchemaB_1.graphql, GraphqlUsingSchemaB_2.graphql, ... are put in FolderB.

And I modified my Generate Apollo GraphQL API run script into:

APOLLO_FRAMEWORK_PATH="$(eval find $FRAMEWORK_SEARCH_PATHS -name "Apollo.framework" -maxdepth 1)"

if [ -z "$APOLLO_FRAMEWORK_PATH" ]; then
echo "error: Couldn't find Apollo.framework in FRAMEWORK_SEARCH_PATHS; make sure to add the framework to your project."
exit 1
fi

cd "${SRCROOT}/${TARGET_NAME}/FolderA"  //Path to your FolderA
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --schema=SchemaA.json Endpoint_A_API.swift

cd "${SRCROOT}/${TARGET_NAME}/FolderB"  //Path to your FolderB
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --schema=SchemaB.json Endpoint_B_API.swift

Now after I built the project, I go to these folders and drag those API.swift into my project.
That's it.

My solution is similar to @daoseng33 's.

I placed my .graphql files and schema.json corresponding to each endpoints into two different folders.

For example,
SchemaA.json, GraphqlUsingSchemaA_1.graphql, GraphqlUsingSchemaA_2.graphql, ... are put in FolderA.
SchemaB.json, GraphqlUsingSchemaB_1.graphql, GraphqlUsingSchemaB_2.graphql, ... are put in FolderB.

And I modified my Generate Apollo GraphQL API run script into:

APOLLO_FRAMEWORK_PATH="$(eval find $FRAMEWORK_SEARCH_PATHS -name "Apollo.framework" -maxdepth 1)"

if [ -z "$APOLLO_FRAMEWORK_PATH" ]; then
echo "error: Couldn't find Apollo.framework in FRAMEWORK_SEARCH_PATHS; make sure to add the framework to your project."
exit 1
fi

cd "${SRCROOT}/${TARGET_NAME}/FolderA"  //Path to your FolderA
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --schema=SchemaA.json Endpoint_A_API.swift

cd "${SRCROOT}/${TARGET_NAME}/FolderB"  //Path to your FolderB
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --schema=SchemaB.json Endpoint_B_API.swift

Now after I built the project, I go to these folders and drag those API.swift into my project.
That's it.

thank you, you solve my problem

@sumanthByton Whoah super late to the response on this one sorry. I ended up actually pulling things out into separate private cocoapods that manage their own schemas and services and built clients around them. It allowed me to easily version and branch individually which was becoming a pain too.

Thanks everyone for your suggestions on this - I don't think we have an official recommendation but I know folks searching for how to do this will appreciate it.

For what it's worth I would personally recommend pulling things into frameworks and/or pods per API - @OrestNazarewycz gave a great reason for it but it also helps in terms of being able to reuse that framework for assorted extensions.

I'm going to close this out since it's mostly suggestions rather than active problems, but thank you all for sharing!

Hi,
thanks for the solutions, I've done exactly what you suggest.
What I don't understand is:

  • if I build/archive with a particular schema how Xcode recognize to use DebugAPI.swift or ReleaseAPI.swift since both are included and added to the project?

Sorry for the question but I'm quite new to GraphQL.

@jerrygdm That's something you'd need to do programmatically at runtime if both APIs are available. It should be pretty similar to saying "I want to use this URL for debug and this URL for release", if the APIs are the same.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

farice picture farice  路  4Comments

hiteshborse12 picture hiteshborse12  路  4Comments

sfla picture sfla  路  3Comments

maxsz picture maxsz  路  4Comments

ashiemke picture ashiemke  路  5Comments