@apollo/gateway
Advanced tools
Comparing version 0.1.5 to 0.1.6
@@ -1,2 +0,2 @@ | ||
import { GraphQLRequest, GraphQLResponse } from 'apollo-server-core'; | ||
import { GraphQLRequestContext, GraphQLResponse } from 'apollo-server-core'; | ||
import { GraphQLSchema, DocumentNode } from 'graphql'; | ||
@@ -7,5 +7,5 @@ import { GraphQLDatasource } from './types'; | ||
constructor(schema: GraphQLSchema); | ||
process(request: GraphQLRequest): Promise<GraphQLResponse>; | ||
process<TContext>({ request, }: Pick<GraphQLRequestContext<TContext>, 'request' | 'context'>): Promise<GraphQLResponse>; | ||
sdl(): DocumentNode; | ||
} | ||
//# sourceMappingURL=LocalGraphQLDatasource.d.ts.map |
@@ -10,3 +10,3 @@ "use strict"; | ||
} | ||
async process(request) { | ||
async process({ request, }) { | ||
return graphql_1.graphql({ | ||
@@ -13,0 +13,0 @@ schema: this.schema, |
@@ -1,3 +0,4 @@ | ||
import { GraphQLRequest, GraphQLResponse, GraphQLRequestContext } from 'apollo-server-core'; | ||
import { Response, ValueOrPromise } from 'apollo-server-env'; | ||
import { GraphQLRequestContext, GraphQLResponse } from 'apollo-server-core'; | ||
import { ApolloError } from 'apollo-server-errors'; | ||
import { Request, Response, ValueOrPromise } from 'apollo-server-env'; | ||
import { GraphQLDatasource } from './types'; | ||
@@ -7,6 +8,9 @@ export declare class RemoteGraphQLDatasource implements GraphQLDatasource { | ||
url: string; | ||
process(request: GraphQLRequest): Promise<GraphQLResponse>; | ||
willSendRequest?(requestContext: GraphQLRequestContext): ValueOrPromise<void>; | ||
process<TContext>({ request, context, }: Pick<GraphQLRequestContext<TContext>, 'request' | 'context'>): Promise<GraphQLResponse>; | ||
protected willSendRequest?<TContext>(requestContext: Pick<GraphQLRequestContext<TContext>, 'request' | 'context'>): ValueOrPromise<void>; | ||
protected didReceiveResponse<TResult = any>(response: Response, _request: Request): Promise<TResult>; | ||
protected didEncounterError(error: Error, _request: Request): void; | ||
protected parseBody(response: Response): Promise<object | string>; | ||
protected errorFromResponse(response: Response): Promise<ApolloError>; | ||
} | ||
//# sourceMappingURL=RemoteGraphQLDatasource.d.ts.map |
"use strict"; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) | ||
t[p[i]] = s[p[i]]; | ||
return t; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const apollo_server_errors_1 = require("apollo-server-errors"); | ||
const apollo_server_env_1 = require("apollo-server-env"); | ||
@@ -11,18 +21,41 @@ const predicates_1 = require("../utilities/predicates"); | ||
} | ||
async process(request) { | ||
async process({ request, context, }) { | ||
const headers = new apollo_server_env_1.Headers(); | ||
headers.set('Content-Type', 'application/json'); | ||
const httpRequest = new apollo_server_env_1.Request(this.url, { | ||
request.http = { | ||
method: 'POST', | ||
url: this.url, | ||
headers, | ||
body: JSON.stringify(request), | ||
}); | ||
const httpResponse = await apollo_server_env_1.fetch(httpRequest); | ||
const body = await this.parseBody(httpResponse); | ||
if (!predicates_1.isObject(body)) { | ||
throw new Error(`Expected JSON response body, but received: ${body}`); | ||
}; | ||
if (this.willSendRequest) { | ||
await this.willSendRequest({ request, context }); | ||
} | ||
const response = Object.assign({}, body, { http: httpResponse }); | ||
return response; | ||
const { http } = request, graphqlRequest = __rest(request, ["http"]); | ||
const options = Object.assign({}, http, { body: JSON.stringify(graphqlRequest) }); | ||
const httpRequest = new apollo_server_env_1.Request(request.http.url, options); | ||
try { | ||
const httpResponse = await apollo_server_env_1.fetch(httpRequest); | ||
const body = await this.didReceiveResponse(httpResponse, httpRequest); | ||
if (!predicates_1.isObject(body)) { | ||
throw new Error(`Expected JSON response body, but received: ${body}`); | ||
} | ||
const response = Object.assign({}, body, { http: httpResponse }); | ||
return response; | ||
} | ||
catch (error) { | ||
this.didEncounterError(error, httpRequest); | ||
throw error; | ||
} | ||
} | ||
async didReceiveResponse(response, _request) { | ||
if (response.ok) { | ||
return this.parseBody(response); | ||
} | ||
else { | ||
throw await this.errorFromResponse(response); | ||
} | ||
} | ||
didEncounterError(error, _request) { | ||
throw error; | ||
} | ||
parseBody(response) { | ||
@@ -37,4 +70,27 @@ const contentType = response.headers.get('Content-Type'); | ||
} | ||
async errorFromResponse(response) { | ||
const message = `${response.status}: ${response.statusText}`; | ||
let error; | ||
if (response.status === 401) { | ||
error = new apollo_server_errors_1.AuthenticationError(message); | ||
} | ||
else if (response.status === 403) { | ||
error = new apollo_server_errors_1.ForbiddenError(message); | ||
} | ||
else { | ||
error = new apollo_server_errors_1.ApolloError(message); | ||
} | ||
const body = await this.parseBody(response); | ||
Object.assign(error.extensions, { | ||
response: { | ||
url: response.url, | ||
status: response.status, | ||
statusText: response.statusText, | ||
body, | ||
}, | ||
}); | ||
return error; | ||
} | ||
} | ||
exports.RemoteGraphQLDatasource = RemoteGraphQLDatasource; | ||
//# sourceMappingURL=RemoteGraphQLDatasource.js.map |
@@ -1,5 +0,5 @@ | ||
import { GraphQLRequest, GraphQLResponse } from 'apollo-server-core'; | ||
import { GraphQLResponse, GraphQLRequestContext } from 'apollo-server-core'; | ||
export interface GraphQLDatasource { | ||
process(request: GraphQLRequest): Promise<GraphQLResponse>; | ||
process<TContext>(request: Pick<GraphQLRequestContext<TContext>, 'request' | 'context'>): Promise<GraphQLResponse>; | ||
} | ||
//# sourceMappingURL=types.d.ts.map |
@@ -8,4 +8,4 @@ import { GraphQLExecutionResult, GraphQLRequestContext } from 'apollo-server-core'; | ||
}; | ||
export declare function executeQueryPlan(queryPlan: QueryPlan, serviceMap: ServiceMap, requestContext: GraphQLRequestContext, operationContext: OperationContext): Promise<GraphQLExecutionResult>; | ||
export declare function executeQueryPlan<TContext>(queryPlan: QueryPlan, serviceMap: ServiceMap, requestContext: GraphQLRequestContext<TContext>, operationContext: OperationContext): Promise<GraphQLExecutionResult>; | ||
export declare const defaultFieldResolverWithAliasSupport: GraphQLFieldResolver<any, any>; | ||
//# sourceMappingURL=executeQueryPlan.d.ts.map |
@@ -89,3 +89,3 @@ "use strict"; | ||
} | ||
const dataReceivedFromService = await sendOperation(operationForRootFetch(fetch, operationType), variables); | ||
const dataReceivedFromService = await sendOperation(context, operationForRootFetch(fetch, operationType), variables); | ||
for (const entity of entities) { | ||
@@ -106,5 +106,3 @@ deepMerge_1.deepMerge(entity, dataReceivedFromService); | ||
}); | ||
const dataReceivedFromService = await sendOperation(operationForEntitiesFetch(fetch), { | ||
representations, | ||
}); | ||
const dataReceivedFromService = await sendOperation(context, operationForEntitiesFetch(fetch), { representations }); | ||
if (!dataReceivedFromService) { | ||
@@ -125,7 +123,10 @@ return; | ||
} | ||
async function sendOperation(operation, variables) { | ||
async function sendOperation(context, operation, variables) { | ||
const source = graphql_1.print(operation); | ||
const response = await service.process({ | ||
query: source, | ||
variables, | ||
request: { | ||
query: source, | ||
variables, | ||
}, | ||
context: context.requestContext.context, | ||
}); | ||
@@ -132,0 +133,0 @@ if (response.errors) { |
@@ -37,3 +37,3 @@ import { GraphQLExecutor, GraphQLExecutionResult, GraphQLRequestContext } from 'apollo-server-core'; | ||
schema: GraphQLSchema | undefined; | ||
executor: <TContext = Record<string, any>>(requestContext: WithRequired<GraphQLRequestContext<TContext>, "document" | "operation" | "queryHash">) => Promise<GraphQLExecutionResult>; | ||
executor: <TContext>(requestContext: WithRequired<GraphQLRequestContext<TContext>, "document" | "operation" | "queryHash">) => Promise<GraphQLExecutionResult>; | ||
}>; | ||
@@ -43,3 +43,3 @@ protected createSchema(services: ServiceDefinition[]): void; | ||
protected loadServiceDefinitions(config: GatewayConfig): Promise<[ServiceDefinition[], boolean]>; | ||
executor: <TContext = Record<string, any>>(requestContext: WithRequired<GraphQLRequestContext<TContext>, "document" | "operation" | "queryHash">) => Promise<GraphQLExecutionResult>; | ||
executor: <TContext>(requestContext: WithRequired<GraphQLRequestContext<TContext>, "document" | "operation" | "queryHash">) => Promise<GraphQLExecutionResult>; | ||
private initializeQueryPlanStore; | ||
@@ -46,0 +46,0 @@ } |
{ | ||
"name": "@apollo/gateway", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"description": "Apollo Gateway", | ||
@@ -30,3 +30,3 @@ "author": "opensource@apollographql.com", | ||
}, | ||
"gitHead": "4c53118cd2b6cb3c3a22d13ef5cae0e1628c9f63" | ||
"gitHead": "39cf637cbac1d5dca96f3f6967b51dc0dd56fb2c" | ||
} |
import './matchers/toMatchAST'; | ||
import './matchers/toCallService'; | ||
import './matchers/toHaveBeenCalledBefore'; | ||
import './matchers/toHaveFetched'; |
@@ -1,2 +0,2 @@ | ||
import { GraphQLRequest, GraphQLResponse } from 'apollo-server-core'; | ||
import { GraphQLRequestContext, GraphQLResponse } from 'apollo-server-core'; | ||
import { | ||
@@ -19,3 +19,7 @@ GraphQLSchema, | ||
async process(request: GraphQLRequest): Promise<GraphQLResponse> { | ||
async process<TContext>({ | ||
request, | ||
}: Pick<GraphQLRequestContext<TContext>, 'request' | 'context'>): Promise< | ||
GraphQLResponse | ||
> { | ||
return graphql({ | ||
@@ -22,0 +26,0 @@ schema: this.schema, |
@@ -0,9 +1,11 @@ | ||
import { GraphQLRequestContext, GraphQLResponse } from 'apollo-server-core'; | ||
import { | ||
GraphQLRequest, | ||
GraphQLResponse, | ||
GraphQLRequestContext, | ||
} from 'apollo-server-core'; | ||
ApolloError, | ||
AuthenticationError, | ||
ForbiddenError, | ||
} from 'apollo-server-errors'; | ||
import { | ||
fetch, | ||
Request, | ||
RequestInit, | ||
Headers, | ||
@@ -29,29 +31,72 @@ Response, | ||
async process(request: GraphQLRequest): Promise<GraphQLResponse> { | ||
async process<TContext>({ | ||
request, | ||
context, | ||
}: Pick<GraphQLRequestContext<TContext>, 'request' | 'context'>): Promise< | ||
GraphQLResponse | ||
> { | ||
const headers = new Headers(); | ||
headers.set('Content-Type', 'application/json'); | ||
const httpRequest = new Request(this.url, { | ||
request.http = { | ||
method: 'POST', | ||
url: this.url, | ||
headers, | ||
body: JSON.stringify(request), | ||
}); | ||
}; | ||
const httpResponse = await fetch(httpRequest); | ||
const body = await this.parseBody(httpResponse); | ||
if (!isObject(body)) { | ||
throw new Error(`Expected JSON response body, but received: ${body}`); | ||
if (this.willSendRequest) { | ||
await this.willSendRequest({ request, context }); | ||
} | ||
const response: GraphQLResponse = { | ||
...body, | ||
http: httpResponse, | ||
const { http, ...graphqlRequest } = request; | ||
const options: RequestInit = { | ||
...http, | ||
body: JSON.stringify(graphqlRequest), | ||
}; | ||
return response; | ||
const httpRequest = new Request(request.http.url, options); | ||
try { | ||
const httpResponse = await fetch(httpRequest); | ||
const body = await this.didReceiveResponse(httpResponse, httpRequest); | ||
if (!isObject(body)) { | ||
throw new Error(`Expected JSON response body, but received: ${body}`); | ||
} | ||
const response: GraphQLResponse = { | ||
...body, | ||
http: httpResponse, | ||
}; | ||
return response; | ||
} catch (error) { | ||
this.didEncounterError(error, httpRequest); | ||
throw error; | ||
} | ||
} | ||
willSendRequest?(requestContext: GraphQLRequestContext): ValueOrPromise<void>; | ||
protected willSendRequest?<TContext>( | ||
requestContext: Pick< | ||
GraphQLRequestContext<TContext>, | ||
'request' | 'context' | ||
>, | ||
): ValueOrPromise<void>; | ||
protected async didReceiveResponse<TResult = any>( | ||
response: Response, | ||
_request: Request, | ||
): Promise<TResult> { | ||
if (response.ok) { | ||
return (this.parseBody(response) as any) as Promise<TResult>; | ||
} else { | ||
throw await this.errorFromResponse(response); | ||
} | ||
} | ||
protected didEncounterError(error: Error, _request: Request) { | ||
throw error; | ||
} | ||
protected parseBody(response: Response): Promise<object | string> { | ||
@@ -65,2 +110,28 @@ const contentType = response.headers.get('Content-Type'); | ||
} | ||
protected async errorFromResponse(response: Response) { | ||
const message = `${response.status}: ${response.statusText}`; | ||
let error: ApolloError; | ||
if (response.status === 401) { | ||
error = new AuthenticationError(message); | ||
} else if (response.status === 403) { | ||
error = new ForbiddenError(message); | ||
} else { | ||
error = new ApolloError(message); | ||
} | ||
const body = await this.parseBody(response); | ||
Object.assign(error.extensions, { | ||
response: { | ||
url: response.url, | ||
status: response.status, | ||
statusText: response.statusText, | ||
body, | ||
}, | ||
}); | ||
return error; | ||
} | ||
} |
@@ -1,5 +0,7 @@ | ||
import { GraphQLRequest, GraphQLResponse } from 'apollo-server-core'; | ||
import { GraphQLResponse, GraphQLRequestContext } from 'apollo-server-core'; | ||
export interface GraphQLDatasource { | ||
process(request: GraphQLRequest): Promise<GraphQLResponse>; | ||
process<TContext>( | ||
request: Pick<GraphQLRequestContext<TContext>, 'request' | 'context'>, | ||
): Promise<GraphQLResponse>; | ||
} |
@@ -36,14 +36,14 @@ import { | ||
interface ExecutionContext { | ||
interface ExecutionContext<TContext> { | ||
queryPlan: QueryPlan; | ||
operationContext: OperationContext; | ||
serviceMap: ServiceMap; | ||
requestContext: GraphQLRequestContext; | ||
requestContext: GraphQLRequestContext<TContext>; | ||
errors: GraphQLError[]; | ||
} | ||
export async function executeQueryPlan( | ||
export async function executeQueryPlan<TContext>( | ||
queryPlan: QueryPlan, | ||
serviceMap: ServiceMap, | ||
requestContext: GraphQLRequestContext, | ||
requestContext: GraphQLRequestContext<TContext>, | ||
operationContext: OperationContext, | ||
@@ -53,3 +53,3 @@ ): Promise<GraphQLExecutionResult> { | ||
const context: ExecutionContext = { | ||
const context: ExecutionContext<TContext> = { | ||
queryPlan, | ||
@@ -98,4 +98,4 @@ operationContext, | ||
async function executeNode( | ||
context: ExecutionContext, | ||
async function executeNode<TContext>( | ||
context: ExecutionContext<TContext>, | ||
node: PlanNode, | ||
@@ -140,4 +140,4 @@ results: ResultMap | ResultMap[], | ||
async function executeFetch( | ||
context: ExecutionContext, | ||
async function executeFetch<TContext>( | ||
context: ExecutionContext<TContext>, | ||
fetch: FetchNode, | ||
@@ -172,2 +172,3 @@ results: ResultMap | ResultMap[], | ||
const dataReceivedFromService = await sendOperation( | ||
context, | ||
operationForRootFetch(fetch, operationType), | ||
@@ -195,6 +196,5 @@ variables, | ||
const dataReceivedFromService = await sendOperation( | ||
context, | ||
operationForEntitiesFetch(fetch), | ||
{ | ||
representations, | ||
}, | ||
{ representations }, | ||
); | ||
@@ -230,11 +230,15 @@ | ||
async function sendOperation( | ||
async function sendOperation<TContext>( | ||
context: ExecutionContext<TContext>, | ||
operation: OperationDefinitionNode, | ||
variables?: Record<string, any>, | ||
variables: Record<string, any>, | ||
): Promise<ResultMap | void> { | ||
const source = print(operation); | ||
const response = await service.process({ | ||
query: source, | ||
variables, | ||
const response = await service.process<TContext>({ | ||
request: { | ||
query: source, | ||
variables, | ||
}, | ||
context: context.requestContext.context, | ||
}); | ||
@@ -241,0 +245,0 @@ |
@@ -163,3 +163,3 @@ import { | ||
public executor = async <TContext = Record<string, any>>( | ||
public executor = async <TContext>( | ||
requestContext: WithRequired< | ||
@@ -202,3 +202,3 @@ GraphQLRequestContext<TContext>, | ||
const response = await executeQueryPlan( | ||
const response = await executeQueryPlan<TContext>( | ||
queryPlan, | ||
@@ -205,0 +205,0 @@ this.serviceMap, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
310746
137
7413