-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
GraphQL Configuration Options #5782
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
davimacedo
merged 32 commits into
parse-community:master
from
omairvaiyani:graphql-config
Jul 25, 2019
Merged
Changes from 4 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
a22dfe6
add parse-graph-ql configuration for class schema customisation
omairvaiyani 5121073
refactor and add graphql router, controller and config cache
omairvaiyani 51b74a4
Merge pull request #1 from omairvaiyani/graphql-config-modularisation
omairvaiyani 1714528
fix(GraphQLController): add missing check isEnabled
omairvaiyani 078e4ad
chore(GraphQLController): remove awaits from cache put
omairvaiyani 8dba72e
chore(GraphQLController): remove check for if its enabled
omairvaiyani 03400f7
refactor(GraphQLController): only use cache if mounted
omairvaiyani 7334bd7
chore(GraphQLController): group all validation errors and throw at once
omairvaiyani b10d09b
chore(GraphQLSchema): move transformations into controller validation
omairvaiyani eef0b2b
refactor(GraphQL): improve ctrl validation and fix schema usage of co…
omairvaiyani 206f8bc
refactor(GraphQLSchema): remove code related to additional schema
omairvaiyani a2fb12e
fix(GraphQLSchema): fix incorrect default return type for class configs
omairvaiyani 5a7004d
refactor(GraphQLSchema): update staleness check code to account for c…
omairvaiyani eb7356c
fix(GraphQLServer): fix regressed tests due to internal schema changes
omairvaiyani c986320
Merge branch 'master' into graphql-config
omairvaiyani df8aa90
refactor: rename to ParseGraphQLController for consistency
omairvaiyani 8f87292
fix(ParseGraphQLCtrl): numerous fixes for validity checking
omairvaiyani 5ef997c
chore(GraphQL): minor syntax cleanup
omairvaiyani 1f9a7a6
fix(SchemaController): add _GraphQLConfig to volatile classes
omairvaiyani 543b319
refactor(ParseGraphQLServer): return update config value in setGraphQ…
omairvaiyani 091e92f
testing(ParseGraphQL): add test cases for new graphQLConfig
omairvaiyani 704e2fb
Merge branch 'graphql-config' of https://github.com/omairvaiyani/pars…
omairvaiyani a77d2c2
fix(GraphQLController): fix issue where config with multiple items wa…
omairvaiyani 4a139ad
fix(postgres): add _GraphQLConfig default schema on load
omairvaiyani 687c9d6
Merge branch 'master' into graphql-config-merge-master
omairvaiyani 848ea77
Merge pull request #2 from omairvaiyani/graphql-config-merge-master
omairvaiyani 2e0940c
GraphQL @mock directive (#5836)
davimacedo e60e798
Merge branch 'graphql-config' of github.com:omairvaiyani/parse-server…
davimacedo c9595ec
Fix existing tests due to the change from ClassFields to ClassCreateF…
davimacedo aedd4bc
fix(parseClassMutations): safer type transformation based on input type
omairvaiyani 17e4a5a
fix(parseClassMutations): only define necessary input fields
omairvaiyani 441dead
fix(GraphQL): fix incorrect import paths
omairvaiyani File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| import requiredParameter from '../../lib/requiredParameter'; | ||
| import DatabaseController from './DatabaseController'; | ||
| import CacheController from './CacheController'; | ||
|
|
||
| const GraphQLConfigClass = '_GraphQLConfig'; | ||
| const GraphQLConfigId = '1'; | ||
| const GraphQLConfigKey = 'config'; | ||
|
|
||
| class GraphQLController { | ||
| databaseController: DatabaseController; | ||
| cacheController: CacheController; | ||
| isEnabled: boolean; | ||
|
|
||
| constructor(params: { | ||
| databaseController: DatabaseController, | ||
| cacheController: CacheController, | ||
| mountGraphQL: boolean, | ||
| }) { | ||
| this.databaseController = | ||
| params.databaseController || | ||
| requiredParameter( | ||
| `GraphQLController requires a "databaseController" to be instantiated.` | ||
| ); | ||
| this.cacheController = | ||
| params.cacheController || | ||
| requiredParameter( | ||
| `GraphQLController requires a "cacheController" to be instantiated.` | ||
| ); | ||
| this.isEnabled = !!params.mountGraphQL; | ||
| } | ||
|
|
||
| async getGraphQLConfig(): Promise<ParseGraphQLConfig> { | ||
| const _cachedConfig = await this._getCachedGraphQLConfig(); | ||
| if (_cachedConfig) { | ||
| return _cachedConfig; | ||
| } | ||
|
|
||
| const results = await this.databaseController.find( | ||
| GraphQLConfigClass, | ||
| { objectId: GraphQLConfigId }, | ||
| { limit: 1 } | ||
| ); | ||
|
|
||
| let graphQLConfig; | ||
| if (results.length != 1) { | ||
| // If there is no config in the database - return empty config. | ||
| return {}; | ||
| } else { | ||
| graphQLConfig = results[0][GraphQLConfigKey]; | ||
| } | ||
|
|
||
| await this._putCachedGraphQLConfig(graphQLConfig); | ||
omairvaiyani marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| return graphQLConfig; | ||
| } | ||
|
|
||
| async updateGraphQLConfig( | ||
| graphQLConfig: ParseGraphQLConfig | ||
| ): Promise<ParseGraphQLConfig> { | ||
| if(!this.isEnabled) { | ||
omairvaiyani marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| throw new Error('GraphQL is not enabled on this application.'); | ||
| } | ||
| // throws if invalid | ||
| this._validateGraphQLConfig(graphQLConfig); | ||
|
|
||
| // Transform in dot notation to make sure it works | ||
| const update = Object.keys(graphQLConfig).reduce((acc, key) => { | ||
| acc[`${GraphQLConfigKey}.${key}`] = graphQLConfig[key]; | ||
| return acc; | ||
| }, {}); | ||
|
|
||
| await this.databaseController.update( | ||
| GraphQLConfigClass, | ||
| { objectId: GraphQLConfigId }, | ||
| update, | ||
| { upsert: true } | ||
| ); | ||
|
|
||
| await this._putCachedGraphQLConfig(graphQLConfig); | ||
omairvaiyani marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| return { response: { result: true } }; | ||
| } | ||
|
|
||
| async _getCachedGraphQLConfig() { | ||
omairvaiyani marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return this.cacheController.graphQL.get(GraphQLConfigKey); | ||
| } | ||
|
|
||
| async _putCachedGraphQLConfig(graphQLConfig: ParseGraphQLConfig) { | ||
omairvaiyani marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return this.cacheController.graphQL.put( | ||
| GraphQLConfigKey, | ||
| graphQLConfig, | ||
| 60000 | ||
| ); | ||
| } | ||
|
|
||
| _validateGraphQLConfig(graphQLConfig: ?ParseGraphQLConfig): void { | ||
| let errorMessage: string; | ||
| if (!graphQLConfig) { | ||
| errorMessage = 'cannot be undefined, null or empty.'; | ||
| } else if (typeof graphQLConfig !== 'object') { | ||
| errorMessage = 'must be a valid object.'; | ||
| } else { | ||
| const { | ||
| enabledForClasses, | ||
| disabledForClasses, | ||
| classConfigs, | ||
| ...invalidKeys | ||
| } = graphQLConfig; | ||
|
|
||
| if (invalidKeys.length) { | ||
| errorMessage = `encountered invalid keys: ${invalidKeys}`; | ||
| } | ||
| // TODO use more rigirous structural validations | ||
| if (enabledForClasses && !Array.isArray(enabledForClasses)) { | ||
omairvaiyani marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| errorMessage = `"enabledForClasses" is not a valid array.`; | ||
| } | ||
| if (disabledForClasses && !Array.isArray(disabledForClasses)) { | ||
| errorMessage = `"disabledForClasses" is not a valid array.`; | ||
| } | ||
| if (classConfigs && !Array.isArray(classConfigs)) { | ||
| errorMessage = `"classConfigs" is not a valid array.`; | ||
| } | ||
| } | ||
| if (errorMessage) { | ||
| throw new Error(`Invalid graphQLConfig: ${errorMessage}`); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export interface ParseGraphQLConfig { | ||
| enabledForClasses?: string[]; | ||
| disabledForClasses?: string[]; | ||
| classConfigs?: ParseGraphQLClassConfig[]; | ||
| } | ||
|
|
||
| export interface ParseGraphQLClassConfig { | ||
| className: string; | ||
| /* The `type` object contains options for how the class types are generated */ | ||
| type: ?{ | ||
| /* Fields that are allowed when creating or updating an object. */ | ||
| inputFields: | ||
| | ?(string[]) | ||
| | ?{ | ||
| /* Leave blank to allow all available fields in the schema. */ | ||
| create?: string[], | ||
| update?: string[], | ||
| }, | ||
| /* Fields on the edges that can be resolved from a query, i.e. the Result Type. */ | ||
| outputFields: ?(string[]), | ||
| /* Fields by which a query can be filtered, i.e. the `where` object. */ | ||
| constraintFields: ?(string[]), | ||
| /* Fields by which a query can be sorted; suffix with _ASC or _DESC to enforce direction. */ | ||
| sortFields: ?(string[]), | ||
| }; | ||
| /* The `query` object contains options for which class queries are generated */ | ||
| query: ?{ | ||
| get: ?boolean, | ||
| find: ?boolean, | ||
| }; | ||
| /* The `mutation` object contains options for which class mutations are generated */ | ||
| mutation: ?{ | ||
| create: ?boolean, | ||
| update: ?boolean, | ||
| delete: ?boolean, | ||
| }; | ||
| } | ||
|
|
||
| export default GraphQLController; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.