Skip to content

Commit

Permalink
feat(adapters): added apollo server mutation adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
H4ad committed Nov 30, 2022
1 parent b5718f7 commit aa7e3e3
Show file tree
Hide file tree
Showing 4 changed files with 468 additions and 0 deletions.
134 changes: 134 additions & 0 deletions src/adapters/apollo-server/apollo-server-mutation.adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
//#region Imports

import {
AdapterContract,
AdapterRequest,
GetResponseAdapterProps,
OnErrorProps,
} from '../../contracts';
import {
ILogger,
getDefaultIfUndefined,
getEventBodyAsBuffer,
} from '../../core';

//#endregion

/**
* The options for {@link ApolloServerMutationAdapter}
*/
export type ApolloServerMutationAdapterOptions = {
/**
* Specify the name of mutation that will be called when an event was received
*/
mutationName: string;

/**
* Specify the mutation result schema.
* Use this to customize the behavior when you need to return a specific object to be handled by the Adapter, like SQS with Batch Mode.
*
* @defaultValue `{ __typename }`
*/
mutationResultQuery?: string;
};

/**
* The adapter that wraps another adapter to force a transformation of the event data as a mutation to Apollo Server be able to handle.
*/
export class ApolloServerMutationAdapter<
TEvent,
TContext,
TResponse,
TBaseAdapter extends AdapterContract<TEvent, TContext, TResponse>,
> implements AdapterContract<TEvent, TContext, TResponse>
{
//#region Constructor

/**
* The default constructor
*/
constructor(
protected readonly baseAdapter: TBaseAdapter,
protected readonly options: ApolloServerMutationAdapterOptions,
) {}

//#endregion

//#region Public Methods

/**
* {@inheritDoc}
*/
public canHandle(event: unknown, context: TContext, log: ILogger): boolean {
return this.baseAdapter.canHandle(event, context, log);
}

/**
* {@inheritDoc}
*/
public getAdapterName(): string {
return this.baseAdapter.getAdapterName() + 'Mutation';
}

/**
* {@inheritDoc}
*/
public getRequest(
event: TEvent,
context: TContext,
log: ILogger,
): AdapterRequest {
const request = this.baseAdapter.getRequest(event, context, log);

request.method = 'POST';

const operationName = this.options.mutationName;
const mutationResultQuery = getDefaultIfUndefined(
this.options.mutationResultQuery,
'{ __typename }',
);

const mutationBody = JSON.stringify({
operationName,
query: `mutation ${operationName} ($event: String) { ${operationName} (event: $event) ${mutationResultQuery} }`,
variables: {
event: request.body?.toString() || '',
},
});

const [buffer, contentLength] = getEventBodyAsBuffer(mutationBody, false);

request.body = buffer;
request.headers['content-type'] = 'application/json';
request.headers['content-length'] = String(contentLength);

return request;
}

/**
* {@inheritDoc}
*/
public getResponse(props: GetResponseAdapterProps<TEvent>): TResponse {
const { data, errors } = JSON.parse(props.body);

if (!errors) {
return this.baseAdapter.getResponse({
...props,
body: JSON.stringify(data[this.options.mutationName]),
});
}

// when error happens, is the responsability of base adapter
// to deal with error status code.
return this.baseAdapter.getResponse(props);
}

/**
* {@inheritDoc}
*/
public onErrorWhileForwarding(props: OnErrorProps<TEvent, TResponse>): void {
return this.baseAdapter.onErrorWhileForwarding(props);
}

//#endregion
}
1 change: 1 addition & 0 deletions src/adapters/apollo-server/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './apollo-server-mutation.adapter';
8 changes: 8 additions & 0 deletions test/adapters/apollo-server/apollo-mutation.adapter.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
describe('ApolloServerMutationAdapter', () => {
// very ugly, i know, but i didn't find any other way, sorry
if (process.env.TEST_NODE_VERSION === '12.x') {
it('when nodejs is 12.x', () => {
expect(true).toEqual(true);
});
} else require('./utils-apollo-mutation').runApolloServerTests();
});
Loading

0 comments on commit aa7e3e3

Please sign in to comment.