-
Notifications
You must be signed in to change notification settings - Fork 348
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(runtime): choose correct root type name for the source (#4571)
* fix(runtime): choose correct root type name for the source * .. * Add more tests * Go * Update get-mesh.ts * chore(dependencies): updated changesets for modified dependencies Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
- Loading branch information
1 parent
6df0993
commit 1a8e808
Showing
6 changed files
with
245 additions
and
4 deletions.
There are no files selected for viewing
This file contains 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,7 @@ | ||
--- | ||
"@graphql-mesh/cli": patch | ||
--- | ||
|
||
dependencies updates: | ||
|
||
- Updated dependency [`[email protected]` ↗︎](https://www.npmjs.com/package/ws/v/8.9.0) (from `8.8.1`, in `dependencies`) |
This file contains 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,7 @@ | ||
--- | ||
"@graphql-mesh/grpc": patch | ||
--- | ||
|
||
dependencies updates: | ||
|
||
- Updated dependency [`[email protected]` ↗︎](https://www.npmjs.com/package/protobufjs/v/7.1.2) (from `7.1.1`, in `dependencies`) |
This file contains 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,7 @@ | ||
--- | ||
"@graphql-mesh/http": patch | ||
--- | ||
|
||
dependencies updates: | ||
|
||
- Updated dependency [`[email protected]` ↗︎](https://www.npmjs.com/package/graphql-yoga/v/3.0.0-next.1) (from `3.0.0-next.0`, in `dependencies`) |
This file contains 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,5 @@ | ||
--- | ||
'@graphql-mesh/runtime': patch | ||
--- | ||
|
||
Choose the root type name for a specific operation type from the source schema not from the gateway schema, because source schema might have a different like `QueryType` instead of `Query`. |
This file contains 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 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,211 @@ | ||
/* eslint-disable import/no-extraneous-dependencies */ | ||
import LocalforageCache from '@graphql-mesh/cache-localforage'; | ||
import GraphQLHandler from '@graphql-mesh/graphql'; | ||
import StitchingMerger from '@graphql-mesh/merger-stitching'; | ||
import { InMemoryStoreStorageAdapter, MeshStore } from '@graphql-mesh/store'; | ||
import { defaultImportFn, DefaultLogger, PubSub } from '@graphql-mesh/utils'; | ||
import { makeExecutableSchema } from '@graphql-tools/schema'; | ||
import { printSchemaWithDirectives } from '@graphql-tools/utils'; | ||
import { parse } from 'graphql'; | ||
import { getMesh } from '../src/get-mesh'; | ||
import { MeshResolvedSource } from '../src/types'; | ||
|
||
describe('getMesh', () => { | ||
const baseDir = __dirname; | ||
let cache: LocalforageCache; | ||
let pubsub: PubSub; | ||
let store: MeshStore; | ||
let logger: DefaultLogger; | ||
let merger: StitchingMerger; | ||
beforeEach(() => { | ||
cache = new LocalforageCache(); | ||
pubsub = new PubSub(); | ||
store = new MeshStore('test', new InMemoryStoreStorageAdapter(), { | ||
readonly: false, | ||
validate: false, | ||
}); | ||
logger = new DefaultLogger('Mesh Test'); | ||
merger = new StitchingMerger({ | ||
store, | ||
cache, | ||
pubsub, | ||
logger, | ||
}); | ||
}); | ||
|
||
interface CreateSchemaConfiguration { | ||
suffix: string; | ||
suffixRootTypeNames: boolean; | ||
suffixFieldNames: boolean; | ||
suffixResponses: boolean; | ||
} | ||
|
||
function createGraphQLSchema(config: CreateSchemaConfiguration) { | ||
const queryTypeName = config.suffixRootTypeNames ? `Query${config.suffix}` : 'Query'; | ||
const mutationTypeName = config.suffixRootTypeNames ? `Mutation${config.suffix}` : 'Mutation'; | ||
const subscriptionTypeName = config.suffixRootTypeNames ? `Subscription${config.suffix}` : 'Subscription'; | ||
|
||
return makeExecutableSchema({ | ||
typeDefs: ` | ||
type ${queryTypeName} { | ||
hello${config.suffixFieldNames ? config.suffix : ''}: String | ||
} | ||
type ${mutationTypeName} { | ||
bye${config.suffixFieldNames ? config.suffix : ''}: String | ||
} | ||
type ${subscriptionTypeName} { | ||
wave${config.suffixFieldNames ? config.suffix : ''}: String | ||
} | ||
schema { | ||
query: ${queryTypeName} | ||
mutation: ${mutationTypeName} | ||
subscription: ${subscriptionTypeName} | ||
} | ||
`, | ||
resolvers: { | ||
[queryTypeName]: { | ||
[`hello${config.suffixFieldNames ? config.suffix : ''}`]: () => | ||
`Hello from service${config.suffixResponses ? config.suffix : ''}`, | ||
}, | ||
[mutationTypeName]: { | ||
[`bye${config.suffixFieldNames ? config.suffix : ''}`]: () => | ||
`Bye from service${config.suffixResponses ? config.suffix : ''}schema`, | ||
}, | ||
}, | ||
}); | ||
} | ||
|
||
function createGraphQLSource(config: CreateSchemaConfiguration): MeshResolvedSource { | ||
const name = `service${config.suffix}`; | ||
return { | ||
name, | ||
handler: new GraphQLHandler({ | ||
baseDir, | ||
cache, | ||
pubsub, | ||
name, | ||
config: { | ||
schema: `./schema${config.suffix}.ts`, | ||
}, | ||
store, | ||
logger, | ||
async importFn(moduleId) { | ||
if (moduleId.endsWith(`schema${config.suffix}.ts`)) { | ||
return createGraphQLSchema(config); | ||
} | ||
return defaultImportFn(moduleId); | ||
}, | ||
}), | ||
transforms: [], | ||
}; | ||
} | ||
|
||
it('handle sources with different query type names', async () => { | ||
const mesh = await getMesh({ | ||
cache, | ||
pubsub, | ||
logger, | ||
sources: new Array(3).fill(0).map((_, i) => | ||
createGraphQLSource({ | ||
suffix: i.toString(), | ||
suffixRootTypeNames: true, | ||
suffixFieldNames: false, | ||
suffixResponses: false, | ||
}) | ||
), | ||
merger, | ||
}); | ||
|
||
expect(printSchemaWithDirectives(mesh.schema)).toMatchInlineSnapshot(` | ||
"schema { | ||
query: Query | ||
mutation: Mutation | ||
subscription: Subscription | ||
} | ||
type Query { | ||
hello: String | ||
} | ||
type Mutation { | ||
bye: String | ||
} | ||
type Subscription { | ||
wave: String | ||
}" | ||
`); | ||
|
||
const result = await mesh.execute( | ||
` | ||
{ | ||
hello0 | ||
hello1 | ||
hello2 | ||
} | ||
`, | ||
{} | ||
); | ||
|
||
expect(result).toMatchInlineSnapshot(` | ||
{ | ||
"data": {}, | ||
} | ||
`); | ||
}); | ||
|
||
it('can stitch a mutation field to a query field', async () => { | ||
const mesh = await getMesh({ | ||
cache, | ||
pubsub, | ||
logger, | ||
merger, | ||
sources: [ | ||
createGraphQLSource({ | ||
suffix: 'Foo', | ||
suffixRootTypeNames: false, | ||
suffixFieldNames: true, | ||
suffixResponses: true, | ||
}), | ||
createGraphQLSource({ | ||
suffix: 'Bar', | ||
suffixRootTypeNames: false, | ||
suffixFieldNames: true, | ||
suffixResponses: true, | ||
}), | ||
], | ||
additionalTypeDefs: [ | ||
parse(/* GraphQL */ ` | ||
extend type Mutation { | ||
strikeBack: String | ||
} | ||
`), | ||
], | ||
additionalResolvers: { | ||
Mutation: { | ||
strikeBack: (root, args, context, info) => context.serviceFoo.Query.helloFoo({ root, args, context, info }), | ||
}, | ||
}, | ||
}); | ||
|
||
const result = await mesh.execute( | ||
/* GraphQL */ ` | ||
mutation { | ||
strikeBack | ||
} | ||
`, | ||
{} | ||
); | ||
|
||
expect(result).toMatchInlineSnapshot(` | ||
{ | ||
"data": { | ||
"strikeBack": "Hello from serviceFoo", | ||
}, | ||
} | ||
`); | ||
}); | ||
}); |