Skip to content

Commit

Permalink
feat: update examples
Browse files Browse the repository at this point in the history
Update examples provided in examples/ dir using schema mappers and new apollo libs.
  • Loading branch information
felipebergamin committed Aug 29, 2023
1 parent 47abf08 commit 9d99ed5
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 90 deletions.
96 changes: 52 additions & 44 deletions examples/access-control-directives.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { ApolloServer } from 'apollo-server';
import type { ExpressContext } from 'apollo-server-express';
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import { makeExecutableSchema } from '@graphql-tools/schema';
import gql from 'graphql-tag';

import applyDirectiveMappersToSchema from 'lib/utils/applyDirectiveMappersToSchema';

import type { MissingPermissionsResolverInfo } from '../lib';
import { v3Auth, v3HasPermissions } from '../lib';
import {
v3Auth,
v3HasPermissions,
authDirectiveMapper,
hasPermissionsDirectiveMapper,
} from '../lib';

const yourTypeDefs = [
gql`
Expand All @@ -29,51 +36,54 @@ const state: {
isAuthenticated: null,
};

const schema = makeExecutableSchema({
resolvers: {
Mutation: {
setAuthenticated: (
_,
{ isAuthenticated }: { isAuthenticated: boolean | null },
): boolean | null => {
state.isAuthenticated = isAuthenticated;
return isAuthenticated;
const schema = applyDirectiveMappersToSchema(
[hasPermissionsDirectiveMapper, authDirectiveMapper],
makeExecutableSchema({
resolvers: {
Mutation: {
setAuthenticated: (
_,
{ isAuthenticated }: { isAuthenticated: boolean | null },
): boolean | null => {
state.isAuthenticated = isAuthenticated;
return isAuthenticated;
},
setPermissions: (
_,
{ permissions }: { permissions: string[] | null },
): string[] | null => {
state.grantedPermissions = permissions;
return permissions;
},
},
setPermissions: (
_,
{ permissions }: { permissions: string[] | null },
): string[] | null => {
state.grantedPermissions = permissions;
return permissions;
Query: {
authenticated: (): boolean => state.isAuthenticated || false,
handleMissingPermissions: (
_,
__,
___,
{ missingPermissions }: MissingPermissionsResolverInfo,
): string[] | null => missingPermissions || null,
throwIfMissingPermissions: (): number => 123,
},
},
Query: {
authenticated: (): boolean => true,
handleMissingPermissions: (
_,
__,
___,
{ missingPermissions }: MissingPermissionsResolverInfo,
): string[] | null => missingPermissions || null,
throwIfMissingPermissions: (): number => 123,
},
},
schemaDirectives: {
v3Auth,
v3HasPermissions,
},
typeDefs: [
...yourTypeDefs,
...v3Auth.getTypeDefs(),
...v3HasPermissions.getTypeDefs(),
],
});
typeDefs: [
...yourTypeDefs,
...v3Auth.getTypeDefs(),
...v3HasPermissions.getTypeDefs(),
],
}),
);

type Context = ReturnType<typeof v3Auth.createDirectiveContext> &
ReturnType<typeof v3HasPermissions.createDirectiveContext>;

const server = new ApolloServer({
context: (expressContext: ExpressContext): Context => {
schema,
});

startStandaloneServer(server, {
context: async (expressContext): Promise<Context> => {
// This example allows for state to be passed in the headers:
// - authorization: any value results in authenticated
// - permissions: json-serialized array of strings or null
Expand Down Expand Up @@ -102,9 +112,7 @@ const server = new ApolloServer({
}),
};
},
schema,
});
server.listen().then(({ url }) => {
// eslint-disable-next-line no-console
listen: { port: 4000 },
}).then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
31 changes: 21 additions & 10 deletions examples/federation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import type {
DocumentNode,
GraphQLFieldResolver,
} from 'graphql';
import { ApolloServer, gql } from 'apollo-server';
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import { ApolloGateway } from '@apollo/gateway';
import { buildSubgraphSchema } from '@apollo/federation';
import { buildSubgraphSchema } from '@apollo/subgraph';
import type { GraphQLResolverMap } from 'apollo-graphql';
import { SchemaDirectiveVisitor } from '@graphql-tools/utils';
import gql from 'graphql-tag';

import { ValidateDirectiveVisitor, range, stringLength } from '../lib';
import { rangeDirectiveMapper } from 'lib/range';
import { stringLengthDirectiveMapper } from 'lib/stringLength';

/*
When using apollo federation all
Expand All @@ -33,9 +36,14 @@ const buildSchema = (
[],
),
];
const schema = buildSubgraphSchema({ resolvers, typeDefs: finalTypeDefs });
SchemaDirectiveVisitor.visitSchemaDirectives(schema, directives);
ValidateDirectiveVisitor.addValidationResolversToSchema(schema);
const schema = stringLengthDirectiveMapper(
rangeDirectiveMapper(
buildSubgraphSchema({
resolvers: resolvers as GraphQLResolverMap<unknown>,
typeDefs: finalTypeDefs,
}),
),
);
return schema;
};

Expand Down Expand Up @@ -83,9 +91,12 @@ const services: ServicesSetup[] = [
const start = async (): Promise<void> => {
const runningString = await Promise.all(
services.map(({ resolvers, typeDefs, port }) =>
new ApolloServer({
schema: buildSchema(resolvers, typeDefs),
}).listen({ port }),
startStandaloneServer(
new ApolloServer({
schema: buildSchema(resolvers, typeDefs),
}),
{ listen: { port } },
),
),
);
// eslint-disable-next-line no-console
Expand All @@ -106,7 +117,7 @@ const start = async (): Promise<void> => {
gateway: apolloGateway,
});

const { url } = await server.listen();
const { url } = await startStandaloneServer(server);
// eslint-disable-next-line no-console
console.log(`🚀 Server ready at ${url}`);
};
Expand Down
78 changes: 42 additions & 36 deletions examples/value-validation-directives.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ApolloServer } from 'apollo-server';
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import { makeExecutableSchema } from '@graphql-tools/schema';
import gql from 'graphql-tag';
import type { ValidationError } from 'apollo-server-errors';

import type { GraphQLResolveInfo } from 'graphql';
import { graphql, print } from 'graphql';
Expand All @@ -13,7 +13,14 @@ import {
stringLength,
ValidateDirectiveVisitor,
trim,
listLengthDirectiveMapper,
patternDirectiveMapper,
rangeDirectiveMapper,
stringLengthDirectiveMapper,
trimDirectiveMapper,
} from '../lib';
import type ValidationError from '../lib/errors/ValidationError';
import applyDirectiveMappersToSchema from 'lib/utils/applyDirectiveMappersToSchema';

interface ValidationErrorsResolverInfo extends GraphQLResolveInfo {
validationErrors?: ValidationError[];
Expand Down Expand Up @@ -82,40 +89,39 @@ const argsResolver = (
{ validationErrors }: ValidationErrorsResolverInfo,
): object => ({ arg, validationErrors });

const schemaDirectives = {
listLength,
pattern,
range,
stringLength,
trim,
};
const mappers = [
listLengthDirectiveMapper,
patternDirectiveMapper,
rangeDirectiveMapper,
stringLengthDirectiveMapper,
trimDirectiveMapper,
];

const schema = makeExecutableSchema({
resolvers: {
Query: {
floatRangeExample: argsResolver,
intRangeExample: argsResolver,
listLengthExample: argsResolver,
patternExample: argsResolver,
stringLengthExample: argsResolver,
throwingIntRangeExample: argsResolver,
trimExample: argsResolver,
const schema = applyDirectiveMappersToSchema(
mappers,
makeExecutableSchema({
resolvers: {
Query: {
floatRangeExample: argsResolver,
intRangeExample: argsResolver,
listLengthExample: argsResolver,
patternExample: argsResolver,
stringLengthExample: argsResolver,
throwingIntRangeExample: argsResolver,
trimExample: argsResolver,
},
},
},
schemaDirectives,
typeDefs: [
...yourTypeDefs,
...ValidateDirectiveVisitor.getMissingCommonTypeDefs(),
...listLength.getTypeDefs(),
...pattern.getTypeDefs(),
...range.getTypeDefs(),
...stringLength.getTypeDefs(),
...trim.getTypeDefs(),
],
});

// needed to validate input fields!
ValidateDirectiveVisitor.addValidationResolversToSchema(schema);
typeDefs: [
...yourTypeDefs,
...ValidateDirectiveVisitor.getMissingCommonTypeDefs(),
...listLength.getTypeDefs(),
...pattern.getTypeDefs(),
...range.getTypeDefs(),
...stringLength.getTypeDefs(),
...trim.getTypeDefs(),
],
}),
);

// works as test and sample queries
const tests = {
Expand Down Expand Up @@ -333,7 +339,7 @@ const test = async (): Promise<void[]> =>
Object.entries(tests).map(
async ([name, { query, result: expected }]): Promise<void> => {
const source = print(query);
const result = await graphql(schema, source);
const result = await graphql({ schema, source });
if (JSON.stringify(result) !== JSON.stringify(expected)) {
throw Error(`test ${name} failed`);
}
Expand All @@ -350,7 +356,7 @@ test().catch(error => {
});

const server = new ApolloServer({ schema });
server.listen().then(({ url }) => {
startStandaloneServer(server).then(({ url }) => {
// eslint-disable-next-line no-console
console.log(`🚀 Server ready at ${url}`);
});

0 comments on commit 9d99ed5

Please sign in to comment.