Last active
October 20, 2021 20:13
-
-
Save iDVB/b009ecfbce5f40fed5d8ab09c808fd66 to your computer and use it in GitHub Desktop.
Apollo Proxy for Remote Schema
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
import { Handler } from 'aws-lambda' | |
import { ApolloServer } from 'apollo-server-lambda' | |
import { makeExecutableSchema, mergeSchemas } from '@graphql-tools/schema' | |
import { introspectSchema, wrapSchema } from '@graphql-tools/wrap' | |
import { AsyncExecutor } from '@graphql-tools/utils' | |
import { fetch } from 'cross-fetch' | |
import { printSchema, print } from 'graphql' | |
const { CONTENTFUL_CDA, CONTENTFUL_SPACE } = process.env | |
const executor: AsyncExecutor = async ({ document, variables }) => { | |
const query = print(document) | |
const fetchResult = await fetch( | |
`https://graphql.contentful.com/content/v1/spaces/${CONTENTFUL_SPACE}`, | |
{ | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
Authorization: `Bearer ${CONTENTFUL_CDA}`, | |
}, | |
body: JSON.stringify({ query, variables }), | |
}, | |
) | |
return fetchResult.json() | |
} | |
const handler: Handler = async (event, context, callback) => { | |
// console.log({ event }) | |
const role = event.requestContext?.authorizer?.role | |
console.log({ requestContext: event.requestContext, role }) | |
const remoteSchema = wrapSchema({ | |
schema: await introspectSchema(executor), | |
executor, | |
}) | |
const localSchema = makeExecutableSchema({ | |
typeDefs: printSchema(remoteSchema) + localExtensions, | |
resolvers: localResolvers, | |
}) | |
const mergedSchema = mergeSchemas({ | |
schemas: [remoteSchema, localSchema], | |
}) | |
const server = new ApolloServer({ | |
schema: mergedSchema, | |
context: { | |
role, | |
}, | |
// introspection: true, | |
// plugins: [ApolloServerPluginLandingPageGraphQLPlayground()], | |
}) | |
const createServer = server.createHandler() | |
return createServer(event, context, callback) | |
} | |
export const localExtensions = ` | |
scalar _Any | |
scalar _FieldSet | |
type _Service { | |
sdl: String | |
} | |
extend type Query { | |
_service: _Service! | |
} | |
directive @external on FIELD_DEFINITION | |
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION | |
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION | |
directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE | |
# this is an optional directive discussed below | |
directive @extends on OBJECT | INTERFACE | |
extend type VideoPost { | |
url: String @requires(fields: "restrictToRoles") | |
}` | |
const localResolvers = { | |
VideoPost: { | |
url: (parent: any, args: any, context: any, info: any) => { | |
const isAllowed = | |
!parent.restrictToRoles?.length || parent.restrictToRoles?.includes(context.role) | |
console.log({ parent, args, context, info }) | |
return isAllowed ? parent.url : null | |
}, | |
}, | |
} | |
export { handler } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment