Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit de8a916

Browse files
committedMar 24, 2021
Changed requestOptions as function so that we can change options depending on the request
1 parent 4e0ca05 commit de8a916

10 files changed

+82
-85
lines changed
 

‎packages/openapi-to-graphql/README.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,10 @@ Resolver options:
176176

177177
- `qs` (type: `object`, default: `{}`): Query parameters to be sent in every request to the API. Parameters defined in the OpenAPI Specification and set by these query parameters will be ignored by OpenAPI-to-GraphQL.
178178

179-
- `requestOptions` (type: `object`, default: `{}`): Additional [options](https://github.com/request/request#requestoptions-callback), provided by the [`Request` module](https://github.com/request/request), that can be used to configure the HTTP calls that powers the generated GraphQL resolvers. A common use case for this option is to set up a web proxy with the `proxy` field. Parameters defined in the OpenAPI Specification and set by this option will be ignored by OpenAPI-to-GraphQL. Additionally, the `headers` field has the feature of being used as a function. If used as a function, the following parameters will be exposed per-request: the operation's `method`, the operation's `path`, the API `title`, and `resolverParams` (the [GraphQL resolver's parameters](https://graphql.org/learn/execution/#root-fields-resolvers)). The function should return the desired headers.
179+
- `requestOptions` (type: `object` | `function`, default: `{}`): Additional [options](https://github.com/request/request#requestoptions-callback), provided by the [`Request` module](https://github.com/request/request), that can be used to configure the HTTP calls that powers the generated GraphQL resolvers. A common use case for this option is to set up a web proxy with the `proxy` field. Parameters defined in the OpenAPI Specification and set by this option will be ignored by OpenAPI-to-GraphQL. Additionally, the `headers` field has the feature of being used as a function. If used as a function, the following parameters will be exposed per-request: the operation's `method`, the operation's `path`, the API `title`, and `resolverParams` (the [GraphQL resolver's parameters](https://graphql.org/learn/execution/#root-fields-resolvers)). The function should return the desired headers. If `requestOptions` is used as a function, the following parameters will be exposed per-request: the operation's `method`, the operation's `path`, the API `title`, and `resolverParams` (the [GraphQL resolver's parameters](https://graphql.org/learn/execution/#root-fields-resolvers)). It should return object of type [options](https://github.com/request/request#requestoptions-callback). If `requestOptions` is used as a function `url` and `method` can also be set.
180180

181181
- `baseUrl` (type: `string`): Used to manually specify the base URL which all paths will be built on. Normally, OpenAPI-to-GraphQL will select a base URL from the [server object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#serverObject) defined in the OAS. However, if the server object contains multiple URLs, OpenAPI-to-GraphQL will randomly select one. The purpose of this option is to provide greater control over the base URL in these situations, especially when the OAS cannot be modified. This option may also prove to be useful in testing and development.
182182

183-
- `urlResolver` (type: `object` | `function`, default: `{}`): URL used to send every request to the API. The following parameters will be exposed per-request: the operation's `method`, the operation's `path`, the API `title`, and `resolverParams` (the [GraphQL resolver's parameters](https://graphql.org/learn/execution/#root-fields-resolvers)). The function should return the desired url.
184-
185183
- `customResolvers` (type: `object`, default: `{}`): OpenAPI-to-GraphQL, by default, creates resolver functions that make REST calls to resolve Query and Mutation fields in the generated GraphQL interface. This option allows users to provide custom resolver functions to be used in place of said ones created by OpenAPI-to-GraphQL. The field that the custom resolver will affect is identifed first by the [title](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#infoObject) of the OAS, then the [path](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#paths-object) of the operation, and lastly the [method](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#path-item-object) of the operation. The `customResolvers` object is thus a triply nested object where the outer key is the title, followed by the path, and finally the method, which points to the [resolver function](https://graphql.org/learn/execution/#root-fields-resolvers) itself. The resolver function can use the parameters `obj`, `args`, `context`, and `info` in order to produce the proper data, as do standard [resolver functions](https://graphql.org/learn/execution/#root-fields-resolvers) in GraphQL. Use cases include the resolution of complex relationships between types, implementing performance improvements like caching, or dealing with non-standard authentication requirements. _Note: Because the arguments are provided by the GraphQL interface, they may look different from the [parameters](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#parameterObject) defined by the OAS. For example, they will have [sanitized](https://github.com/IBM/openapi-to-graphql#characteristics) names. The [request body](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#requestBodyObject) will also be contained in the arguments as an [input object type](https://graphql.org/graphql-js/mutations-and-input-types/)._
186184

187185
- `customSubscriptionResolvers` (type: `object`, default: `{}`): If the `createSubscriptionsFromCallbacks` is enabled, OpenAPI-to-GraphQL will generate Subscription fields. This option allows users to provide custom resolver and subscribe functions to be used in place of said ones created by OpenAPI-to-GraphQL. The field that the custom resolver and subscribe functions will affect is identifed first by the [title](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#infoObject) of the OAS, then the [path](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#paths-object) of the operation, and lastly the [method](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#path-item-object) of the operation. The resolver is provided via the `resolver` field and the publish function is provided via the `publish` field. The `customSubscriptionResolvers` object is thus a quadruply nested object where the outer key is the title, followed by the path, then the method, and lastly either `resolver` or `publish` which points to the [resolver function](https://graphql.org/learn/execution/#root-fields-resolvers) itself or publish function. See the [Subscriptions tutorial](./docs/subscriptions.md) for more information. _Note: Because the arguments are provided by the GraphQL interface, they may look different from the [parameters](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#parameterObject) defined by the OAS. For example, they will have [sanitized](https://github.com/IBM/openapi-to-graphql#characteristics) names. The [request body](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#requestBodyObject) will also be contained in the arguments as an [input object type](https://graphql.org/graphql-js/mutations-and-input-types/)._

‎packages/openapi-to-graphql/lib/index.js

+1-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/openapi-to-graphql/lib/index.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/openapi-to-graphql/lib/resolver_builder.d.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/// <reference types="node" />
12
/**
23
* Functions to create resolve functions.
34
*/
@@ -6,7 +7,7 @@ import { ConnectOptions } from './types/options';
67
import { Operation } from './types/operation';
78
import { SubscriptionContext } from './types/graphql';
89
import { PreprocessingData } from './types/preprocessing_data';
9-
import { RequestOptions } from './types/options';
10+
import { RequestOptions, RequestOptionsFunction } from './types/options';
1011
import { GraphQLFieldResolver } from 'graphql';
1112
import { IncomingHttpHeaders } from 'http';
1213
export declare const OPENAPI_TO_GRAPHQL = "_openAPIToGraphQL";
@@ -19,7 +20,7 @@ declare type GetResolverParams<TSource, TContext, TArgs> = {
1920
responseName?: string;
2021
data: PreprocessingData<TSource, TContext, TArgs>;
2122
baseUrl?: string;
22-
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>>;
23+
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>> | RequestOptionsFunction<TSource, TContext, TArgs>;
2324
};
2425
declare type GetSubscribeParams<TSource, TContext, TArgs> = {
2526
operation: Operation;

‎packages/openapi-to-graphql/lib/resolver_builder.js

+25-20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/openapi-to-graphql/lib/resolver_builder.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/openapi-to-graphql/lib/types/options.d.ts

+3-12
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,12 @@ export declare type RequestHeadersFunction<TSource, TContext, TArgs> = (method:
4343
context: TContext;
4444
info: GraphQLResolveInfo;
4545
}) => Headers;
46-
/**
47-
* Given a set parameters corresponding to a specific operation in the OAS,
48-
* provide the appropriate url
49-
*/
50-
export declare type RequestURLFunction<TSource, TContext, TArgs> = (method: string, path: string, title: string, resolverParams?: {
46+
export declare type RequestOptionsFunction<TSource, TContext, TArgs> = (method: string, path: string, title: string, resolverParams?: {
5147
source: TSource;
5248
args: TArgs;
5349
context: TContext;
5450
info: GraphQLResolveInfo;
55-
}) => string;
51+
}) => Partial<NodeRequest.CoreOptions>;
5652
/**
5753
* We rely on the Request library in order to make resolver API calls.
5854
*
@@ -185,7 +181,7 @@ export declare type InternalOptions<TSource, TContext, TArgs> = {
185181
*
186182
* Based on: https://github.com/request/request#requestoptions-callback
187183
*/
188-
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>>;
184+
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>> | RequestOptionsFunction<TSource, TContext, TArgs>;
189185
/**
190186
* Allows to override or add options to the PubSub connect object used to make
191187
* publish/subscribe to the API backend.
@@ -197,11 +193,6 @@ export declare type InternalOptions<TSource, TContext, TArgs> = {
197193
* Overrides the server object in the OAS.
198194
*/
199195
baseUrl?: string;
200-
/**
201-
* Specifies the function which returns a URL, which will be used for request made by a resolve function.
202-
* Overrides the server object in the OAS and baseUrl.
203-
*/
204-
urlResolver?: RequestURLFunction<TSource, TContext, TArgs>;
205196
/**
206197
* Allows to define custom resolvers for fields on the Query/Mutation root
207198
* operation type.

‎packages/openapi-to-graphql/src/index.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
InternalOptions,
3737
Report,
3838
ConnectOptions,
39+
RequestOptionsFunction,
3940
RequestOptions
4041
} from './types/options'
4142
import { Oas3 } from './types/oas3'
@@ -203,7 +204,6 @@ function translateOpenAPIToGraphQL<TSource, TContext, TArgs>(
203204
requestOptions,
204205
connectOptions,
205206
baseUrl,
206-
urlResolver,
207207
customResolvers,
208208
customSubscriptionResolvers,
209209

@@ -243,7 +243,6 @@ function translateOpenAPIToGraphQL<TSource, TContext, TArgs>(
243243
requestOptions,
244244
connectOptions,
245245
baseUrl,
246-
urlResolver,
247246
customResolvers,
248247
customSubscriptionResolvers,
249248

@@ -642,7 +641,9 @@ function getFieldForOperation<TSource, TContext, TArgs>(
642641
operation: Operation,
643642
baseUrl: string,
644643
data: PreprocessingData<TSource, TContext, TArgs>,
645-
requestOptions: Partial<RequestOptions<TSource, TContext, TArgs>>,
644+
requestOptions:
645+
| Partial<RequestOptions<TSource, TContext, TArgs>>
646+
| RequestOptionsFunction<TSource, TContext, TArgs>,
646647
connectOptions: ConnectOptions
647648
): GraphQLFieldConfig<TSource, TContext | SubscriptionContext, TArgs> {
648649
// Create GraphQL Type for response:

‎packages/openapi-to-graphql/src/resolver_builder.ts

+34-24
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { Operation } from './types/operation'
1414
import { SubscriptionContext } from './types/graphql'
1515
import { PreprocessingData } from './types/preprocessing_data'
1616
import * as NodeRequest from 'request'
17-
import { RequestOptions } from './types/options'
17+
import { RequestOptions, RequestOptionsFunction } from './types/options'
1818

1919
// Imports:
2020
import * as Oas3Tools from './oas_3_tools'
@@ -57,7 +57,9 @@ type GetResolverParams<TSource, TContext, TArgs> = {
5757
responseName?: string
5858
data: PreprocessingData<TSource, TContext, TArgs>
5959
baseUrl?: string
60-
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>>
60+
requestOptions?:
61+
| Partial<RequestOptions<TSource, TContext, TArgs>>
62+
| RequestOptionsFunction<TSource, TContext, TArgs>
6163
}
6264

6365
type GetSubscribeParams<TSource, TContext, TArgs> = {
@@ -487,7 +489,7 @@ export function getResolver<TSource, TContext, TArgs>({
487489
args,
488490
data
489491
)
490-
const url = baseUrl + path
492+
let url = baseUrl + path
491493

492494
/**
493495
* The Content-Type and Accept property should not be changed because the
@@ -510,21 +512,41 @@ export function getResolver<TSource, TContext, TArgs>({
510512

511513
let options: NodeRequest.OptionsWithUrl
512514
if (requestOptions) {
515+
let requestOptionsVal: any = requestOptions
516+
let method = operation.method
517+
if (typeof requestOptions === 'function') {
518+
requestOptionsVal = requestOptions(method, path, title, {
519+
source,
520+
args,
521+
context,
522+
info
523+
})
524+
525+
if (
526+
requestOptionsVal.url &&
527+
requestOptionsVal.url.toString().trim().length > 0
528+
) {
529+
url = requestOptionsVal.url.toString().trim()
530+
}
531+
if (requestOptionsVal.method && requestOptionsVal.method.length > 0) {
532+
method = Oas3Tools.methodToHttpMethod(requestOptionsVal.method)
533+
}
534+
}
513535
options = {
514-
...requestOptions,
515-
method: operation.method,
536+
...requestOptionsVal,
537+
method: method,
516538
url // Must be after the requestOptions spread as url is a mandatory field so undefined may be used
517539
}
518540

519541
options.headers = {} // Handle requestOptions.header later if applicable
520542
options.qs = {} // Handle requestOptions.qs later if applicable
521543

522-
if (requestOptions.headers) {
544+
if (requestOptionsVal.headers) {
523545
// requestOptions.headers may be either an object or a function
524-
if (typeof requestOptions.headers === 'object') {
525-
Object.assign(options.headers, headers, requestOptions.headers)
526-
} else if (typeof requestOptions.headers === 'function') {
527-
const headers = requestOptions.headers(method, path, title, {
546+
if (typeof requestOptionsVal.headers === 'object') {
547+
Object.assign(options.headers, headers, requestOptionsVal.headers)
548+
} else if (typeof requestOptionsVal.headers === 'function') {
549+
const headers = requestOptionsVal.headers(method, path, title, {
528550
source,
529551
args,
530552
context,
@@ -539,8 +561,8 @@ export function getResolver<TSource, TContext, TArgs>({
539561
options.headers = headers
540562
}
541563

542-
if (requestOptions.qs) {
543-
Object.assign(options.qs, qs, requestOptions.qs)
564+
if (requestOptionsVal.qs) {
565+
Object.assign(options.qs, qs, requestOptionsVal.qs)
544566
} else {
545567
options.qs = qs
546568
}
@@ -644,18 +666,6 @@ export function getResolver<TSource, TContext, TArgs>({
644666
Object.assign(options.headers, oauthHeader)
645667
}
646668

647-
if (data.options.urlResolver) {
648-
const url = data.options.urlResolver(method, path, title, {
649-
source,
650-
args,
651-
context,
652-
info
653-
});
654-
if (typeof url === 'string') {
655-
options.url = url;
656-
}
657-
}
658-
659669
resolveData.usedRequestOptions = options
660670
resolveData.usedStatusCode = operation.statusCode
661671

‎packages/openapi-to-graphql/src/types/options.ts

+9-17
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,17 @@ export type RequestHeadersFunction<TSource, TContext, TArgs> = (
6060
}
6161
) => Headers
6262

63-
/**
64-
* Given a set parameters corresponding to a specific operation in the OAS,
65-
* provide the appropriate url
66-
*/
67-
export type RequestURLFunction<TSource, TContext, TArgs> = (
63+
export type RequestOptionsFunction<TSource, TContext, TArgs> = (
6864
method: string,
6965
path: string,
7066
title: string,
7167
resolverParams?: {
72-
source: TSource;
73-
args: TArgs;
74-
context: TContext;
75-
info: GraphQLResolveInfo;
68+
source: TSource
69+
args: TArgs
70+
context: TContext
71+
info: GraphQLResolveInfo
7672
}
77-
) => string;
73+
) => Partial<NodeRequest.CoreOptions>
7874

7975
/**
8076
* We rely on the Request library in order to make resolver API calls.
@@ -235,7 +231,9 @@ export type InternalOptions<TSource, TContext, TArgs> = {
235231
*
236232
* Based on: https://github.com/request/request#requestoptions-callback
237233
*/
238-
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>>
234+
requestOptions?:
235+
| Partial<RequestOptions<TSource, TContext, TArgs>>
236+
| RequestOptionsFunction<TSource, TContext, TArgs>
239237

240238
/**
241239
* Allows to override or add options to the PubSub connect object used to make
@@ -250,12 +248,6 @@ export type InternalOptions<TSource, TContext, TArgs> = {
250248
*/
251249
baseUrl?: string
252250

253-
/**
254-
* Specifies the function which returns a URL, which will be used for request made by a resolve function.
255-
* Overrides the server object in the OAS and baseUrl.
256-
*/
257-
urlResolver?: RequestURLFunction<TSource, TContext, TArgs>;
258-
259251
/**
260252
* Allows to define custom resolvers for fields on the Query/Mutation root
261253
* operation type.

0 commit comments

Comments
 (0)
Please sign in to comment.