diff --git a/examples/fastify/.meshrc.yml b/examples/fastify/.meshrc.yml index 4b528585e71c1..f1547a053f2de 100644 --- a/examples/fastify/.meshrc.yml +++ b/examples/fastify/.meshrc.yml @@ -1,3 +1,4 @@ +merger: bare sources: - name: Swapi handler: @@ -5,3 +6,7 @@ sources: source: ./swagger/pets.json endpoint: >- http://localhost:4001 + transforms: + - extend: + typeDefs: ./src/extensions/typeDefs.graphql + resolvers: ./src/extensions/resolvers diff --git a/examples/fastify/src/extensions/resolvers.ts b/examples/fastify/src/extensions/resolvers.ts new file mode 100644 index 0000000000000..36ece5dbebffa --- /dev/null +++ b/examples/fastify/src/extensions/resolvers.ts @@ -0,0 +1,37 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import type { Resolvers, MeshContext } from '../../.mesh'; + +const resolvers: Resolvers = { + NewPetResponseUnion: { + __resolveType: (val: any) => { + return (val as any).foo + ? 'NewPetResponse' + : 'Error'; + }, + }, + Query: { + newPet: async (root, args, context: MeshContext, info): Promise => { + const { + petId, + extraId + } = args; + + const data = (await context.Swapi.Query.pet_by_petId({ + root, + args: { + petId + }, + context, + info, + })) as any; + + console.log('Data from pet_by_petId', JSON.stringify(data, null, 4)); + + return { + foo: JSON.stringify(data) + }; + }, + }, +}; + +export default resolvers; diff --git a/examples/fastify/src/extensions/typeDefs.graphql b/examples/fastify/src/extensions/typeDefs.graphql new file mode 100644 index 0000000000000..49bfe131702a2 --- /dev/null +++ b/examples/fastify/src/extensions/typeDefs.graphql @@ -0,0 +1,12 @@ +type NewPetResponse { + foo: String +} + +union NewPetResponseUnion = Error | NewPetResponse + +extend type Query { + newPet( + petId: String! + extraId: String! + ): NewPetResponseUnion +} diff --git a/examples/fastify/src/upstream.ts b/examples/fastify/src/upstream.ts index bb39f660756c8..dfe476f0dff96 100644 --- a/examples/fastify/src/upstream.ts +++ b/examples/fastify/src/upstream.ts @@ -6,12 +6,8 @@ upstream.route({ method: ['GET', 'POST'], url: '/pet/:petId', async handler(request, reply) { - const { petId } = request.params as { petId: string }; - - if (petId === 'pet200') { - return reply.status(200).send({ name: 'Bob' }); - } - - return reply.status(500).send({ error: `Error` }); + return reply.status(200).send({ + "id": "0fc9111f-570d-4ebe-a72e-ff4eb274bc65", + }); }, }); diff --git a/examples/fastify/swagger/pets.json b/examples/fastify/swagger/pets.json index f07d6d5dbe758..2fae8322c6900 100644 --- a/examples/fastify/swagger/pets.json +++ b/examples/fastify/swagger/pets.json @@ -1,46 +1,66 @@ { - "openapi": "3.0.3", + "openapi": "3.0.1", "paths": { - "/pet/{petId}": { - "get": { - "parameters": [ - { - "name": "petId", - "in": "path", - "description": "ID of pet to return", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "successful operation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } + "/pet/{petId}": { + "get": { + "parameters": [ + { + "name": "petId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Returns the Pet", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pet" + } + } + } + }, + "500": { + "description": "Server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } } - } } - } } - } }, "components": { - "schemas": { - "Pet": { - "required": ["name"], - "type": "object", - "properties": { - "name": { - "type": "string", - "example": "doggie" - } + "schemas": { + "Pet": { + "required": [ + "id" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Error": { + "type": "object", + "properties": { + "errors": { + "type": "string" + } + }, + "additionalProperties": false } } - } } } diff --git a/examples/fastify/tests/fastify.spec.ts b/examples/fastify/tests/fastify.spec.ts index e26a787382026..67ff208f0df20 100644 --- a/examples/fastify/tests/fastify.spec.ts +++ b/examples/fastify/tests/fastify.spec.ts @@ -26,16 +26,29 @@ describe('fastify', () => { body: JSON.stringify({ query: /* GraphQL */ ` { - pet_by_petId(petId: "pet200") { - name - } + pet_by_petId(petId: "0fc9111f-570d-4ebe-a72e-ff4eb274bc65"){ + __typename + ... on Pet { + id + } + ... on Error { + errors + } + } } `, }), }); const json = await response.json(); - expect(json.data).toEqual({ pet_by_petId: { name: 'Bob' } }); + expect(json).toEqual({ + data: { + pet_by_petId: { + "__typename": "Pet", + "id": "0fc9111f-570d-4ebe-a72e-ff4eb274bc65", + }, + } + }); }); it('should work too', async () => { @@ -47,28 +60,28 @@ describe('fastify', () => { body: JSON.stringify({ query: /* GraphQL */ ` { - pet_by_petId(petId: "pet500") { - name + newPet(extraId: "dbd9e7c1-24f1-42e8-bd34-e7ce5bbafd7b", petId: "0fc9111f-570d-4ebe-a72e-ff4eb274bc65"){ + __typename + ... on Error { + errors + } + ... on NewPetResponse { + foo + } } } `, }), }); - const resJson = await response.json(); - - expect(resJson).toEqual({ - data: { pet_by_petId: null }, - errors: [ - { - message: 'HTTP Error: 500, Could not invoke operation GET /pet/{args.petId}', - path: ['pet_by_petId'], - extensions: { - request: { url: 'http://localhost:4001/pet/pet500', method: 'GET' }, - responseJson: { error: 'Error' }, - }, - }, - ], + const json = await response.json(); + expect(json).toEqual({ + data: { + "newPet": { + "__typename": "NewPetResponse", + "foo": "{\"__typename\":\"Pet\", \"id\": \"0fc9111f-570d-4ebe-a72e-ff4eb274bc65\"}", + } + } }); }); });