GraphQL Configuration Protocol
See original GitHub issueGraphQL Configuration protocol
In a nutshell, the simplest format is:
export type GraphQLConfiguration = {
schemaPath?: FilePath, // may be .json or .graphql
schemaUrl?: URL,
schemaJS?: ModulePath | ModuleName,
// If env is specified, use one of the app configs in here
env?: GraphQLConfigurationEnvs
// For multiple applications with overlapping files, bottom configuration options may be helpful
includeDirs?: Array<DirPath>,
excludeDirs?: Array<DirPath>,
// If you have customized validation rules to run
customValidationRules?: FilePath | Array<FilePath>,
// If you'd like to specify any other configurations, we provide a reserved namespace for it
extensions?: GraphQLConfigurationExtension
};
export type GraphQLConfigurationEnvs = {
production: GraphQLConfiguration,
development: GraphQLConfiguration,
// but really just the below
[envVarName: string]: GraphQLConfiguration
};
export type GraphQLConfigurationExtension = {
[toolName: string]: any,
};
Note that I’d like to discourage the recursive pattern in using the EnvironmentalVariable
- for example:
{
"schemaPath": "...",
"env": {
"production": {
"appProd": {
// BEWARE OF THE BELOW PATTERN!
"env": { ... }
}
}
}
}
Now the reasoning for it: let’s start with a most simple use case - one app/one schema.
Single-app/single-schema
Usually a single app requires a schema path/url and an env variable to facilitate the build and deployment:
export type GraphQLAppConfig = {
schemaPath: FilePath,
schemaUrl: URL,
env: EnvironmentVariable
};
export type EnvironmentVariable = {
[envVarName: string]: GraphQLAppConfig
};
Multiple-apps/isolated directories
For multiple apps with isolated directories, I like @wincent’s idea about a common-default GraphQL configurations, but in spirit of keeping things simple at first, I’d like to propose an one-config-per-directory approach as our first draft. I think there’s an edge case where we’d have multiple parent GraphQL configurations to consider:
./repo/.graphqlrc
./repo/appFamily/.graphqlrc
./repo/appFamily/app1/.graphqlrc
This can become a discussion of its own, which we can have separately 😉
Custom validation rules
You may want to run custom validation rules before building GraphQL apps/codegen/etc - customValidationRules
is useful for that.
Reserved namespaces
@wincent made a suggestion to provide a way to include any other configurations if you desire. This namespace will contain an app/prod/organization/team-specific GraphQL configurations, and it will be treated as optional settings you’d like to use for your purpose.
{
"schemaPath": "path/to/schema",
"extensions": {
"my-tool": {
"here": "This is a tool-specific extension"
}
}
}
What is this repo, then?
I think this repo should serve two roles in a broader sense:
1. Maintain this protocol and become a town hall for discussions/improvements for this protocol. 2. Provide reference implementations of helper methods to lubricate adoption for this protocol.
An example of the reference implementation of the helper method: we mentioned a way to find this GraphQL configuration is to walk up a directory until it finds one. This basically can be implemented as such:
/**
* (From `graphql-language-service` repo:
* Finds a .graphqlrc configuration file, and returns null if not found.
* If the file isn't present in the provided directory path, walk up the
* directory tree until the file is found or it reaches the root directory.
*/
export function findGraphQLConfigDir(dirPath: string): ?string {
let currentPath = path.resolve(dirPath);
while (true) {
const filePath = path.join(currentPath, '.graphqlrc');
if (fs.existsSync(filePath)) {
break;
}
if (isRootDir(currentPath)) {
break;
}
currentPath = path.dirname(currentPath);
}
return !isRootDir(currentPath) ? currentPath : null;
}
function isRootDIr(path: string): boolean {
return path.dirname(path) === path;
}
As there are several use cases, we can tackle each of them and present a way to use this configuration programmatically. I can begin by identifying/suggesting some of them below:
- A generalized module bundler configurations, using GraphQL configurations
- webpack, yeoman, babel, and etc…
- How to include custom validation rules in your application
- How to generate schema with provided schema path(s)
- Sending introspection query to the endpoint
- Parsing/building the schema using a local file path
- Compiling
GraphQLSchema
object using schema definitions in .js - How to cache the schema
- local files, indexedDB, and etc…
Action items
There are many things to do! But when we successfully deliver this, I believe we can get to the point where we have a shared GraphQL configuration that everyone agrees on, with commonly-used techniques and best practices to configure your GraphQL environment.
- Write a draft for this protocol
- Populate this repository with those helper methods
- Discuss what the superset of those helper methods would be
- Prioritize by the most impactful and common ones and implement them
- Generalize existing implementations and move them here
- Update other remaining documentations, including this repo’s README
- Suggest GraphQL configuration as a best-practice at
graphql.org
Lastly, although we’ve begun this proposal and made a bunch of suggestions, I’d love to have a collaborative effort in pushing this forward. It’ll be amazing to see us working together to improve and deliver this proposal to the GraphQL community.
Please post your thoughts/concerns/questions! Also if you’d like to be responsible for one of the actions items above, don’t be hesitate to do so 😄
Issue Analytics
- State:
- Created 7 years ago
- Reactions:2
- Comments:32 (9 by maintainers)
Top GitHub Comments
Hi @IvanGoncharov, apologies for the radio silence on my end these days. I was meeting with @asiandrummer (and other amazing folks from Facebook) this week and we discussed the next steps for
graphql-config
. (I also discussed this with @jbaxleyiii from Apollo.)We concluded the following:
schemaPath
will be a required configuration option and the only source of truth for the schema. (Both SDL (formerly IDL) and JSON introspection results are supported as source)schemaUrl
option will be replaced by another workflow. Things like HTTP headers etc will be handled by this CLI tool.graphql-config
that other libraries can use (e.g. http endpoint, subscription endpoint)To discuss:
includeDirs
&excludeDirs
& agree on regex formatExamples
To wrap up, here are a few examples using the current format proposal.
Minimal
Multi-project
Also, thanks to everyone’s participations, I feel like we’re ready to move this forward and actually create a PR to add this as a protocol/spec document. I’ll get that done soon - we can continue these valuable conversations over there.