question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

GraphQL Configuration Protocol

See original GitHub issue

GraphQL 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:closed
  • Created 7 years ago
  • Reactions:2
  • Comments:32 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
schicklingcommented, Jul 15, 2017

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)
  • The schemaUrl option will be replaced by another workflow. Things like HTTP headers etc will be handled by this CLI tool.
  • There should be so called “standard extensions” that ship with helper functions in graphql-config that other libraries can use (e.g. http endpoint, subscription endpoint)

To discuss:

  1. Define naming conventions for extensions
  2. Define standard extensions
  3. File format (JSON, YAML, HCL, …)
  4. Default value for includeDirs & excludeDirs & agree on regex format

Examples

To wrap up, here are a few examples using the current format proposal.

Minimal

{
  "schemaPath": "./schema.graphql",
  "extension": {
    "endpoint": "https://api.graph.cool/instagram"
  }
}

Multi-project

{
  "development": {
    "schemaPath": "./dev.graphql",
    "extension": {
      "http-endpoint": "http://localhost:3000/graphql"
    }
  },
  "production": {
    "schemaPath": "./prod.graphql",
    "extension": {
      "http-endpoint": "https://api.graph.cool/instagram"
    }
  }
}
2reactions
asiandrummercommented, Jul 12, 2017

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Serving over HTTP - GraphQL
HTTP is the most common choice for client-server protocol when using GraphQL because of its ubiquity. Here are some guidelines for setting up...
Read more >
An introduction to GraphQL - Sabre
GraphQL is a protocol for communicating with APIs. API stands for “application programming interface.” These are the digital tools that ...
Read more >
Advanced networking configuration - Apollo GraphQL Docs
To learn about configuring your client to support sending subscription operations over a web ... This object conforms to the InterceptorProvider protocol.
Read more >
Protocol Adapters - SAP Capire
Similar to the configuration of the GraphQL Adapter, you can plug in your own protocol. The impl property must point to the implementation...
Read more >
Manual schema configuration :: Gloo Edge Docs
To manually configure GraphQL resolvers, you create a Gloo Edge GraphQL API CRD. The following sections describe the configuration for REST or gRPC...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found