Skip to content

Commit fa6f0ac

Browse files
committed
requestOptions accepting function so that we can change options depending on the request
1 parent 784b89a commit fa6f0ac

9 files changed

+90
-29
lines changed

packages/openapi-to-graphql/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ 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

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ConnectOptions } from './types/options';
77
import { Operation } from './types/operation';
88
import { SubscriptionContext } from './types/graphql';
99
import { PreprocessingData } from './types/preprocessing_data';
10-
import { RequestOptions } from './types/options';
10+
import { RequestOptions, RequestOptionsFunction } from './types/options';
1111
import { GraphQLFieldResolver } from 'graphql';
1212
import { IncomingHttpHeaders } from 'http';
1313
export declare const OPENAPI_TO_GRAPHQL = "_openAPIToGraphQL";
@@ -20,7 +20,7 @@ declare type GetResolverParams<TSource, TContext, TArgs> = {
2020
responseName?: string;
2121
data: PreprocessingData<TSource, TContext, TArgs>;
2222
baseUrl?: string;
23-
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>>;
23+
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>> | RequestOptionsFunction<TSource, TContext, TArgs>;
2424
};
2525
declare type GetSubscribeParams<TSource, TContext, TArgs> = {
2626
operation: Operation;

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

+25-9
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

+7-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ export declare type RequestHeadersFunction<TSource, TContext, TArgs> = (method:
4343
context: TContext;
4444
info: GraphQLResolveInfo;
4545
}) => Headers;
46+
export declare type RequestOptionsFunction<TSource, TContext, TArgs> = (method: string, path: string, title: string, resolverParams?: {
47+
source: TSource;
48+
args: TArgs;
49+
context: TContext;
50+
info: GraphQLResolveInfo;
51+
}) => Partial<NodeRequest.CoreOptions>;
4652
/**
4753
* We rely on the Request library in order to make resolver API calls.
4854
*
@@ -175,7 +181,7 @@ export declare type InternalOptions<TSource, TContext, TArgs> = {
175181
*
176182
* Based on: https://github.com/request/request#requestoptions-callback
177183
*/
178-
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>>;
184+
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>> | RequestOptionsFunction<TSource, TContext, TArgs>;
179185
/**
180186
* Allows to override or add options to the PubSub connect object used to make
181187
* publish/subscribe to the API backend.

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

+4-1
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'
@@ -640,7 +641,9 @@ function getFieldForOperation<TSource, TContext, TArgs>(
640641
operation: Operation,
641642
baseUrl: string,
642643
data: PreprocessingData<TSource, TContext, TArgs>,
643-
requestOptions: Partial<RequestOptions<TSource, TContext, TArgs>>,
644+
requestOptions:
645+
| Partial<RequestOptions<TSource, TContext, TArgs>>
646+
| RequestOptionsFunction<TSource, TContext, TArgs>,
644647
connectOptions: ConnectOptions
645648
): GraphQLFieldConfig<TSource, TContext | SubscriptionContext, TArgs> {
646649
// Create GraphQL Type for response:

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

+34-12
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
}

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

+15-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ export type RequestHeadersFunction<TSource, TContext, TArgs> = (
6060
}
6161
) => Headers
6262

63+
export type RequestOptionsFunction<TSource, TContext, TArgs> = (
64+
method: string,
65+
path: string,
66+
title: string,
67+
resolverParams?: {
68+
source: TSource
69+
args: TArgs
70+
context: TContext
71+
info: GraphQLResolveInfo
72+
}
73+
) => Partial<NodeRequest.CoreOptions>
74+
6375
/**
6476
* We rely on the Request library in order to make resolver API calls.
6577
*
@@ -219,7 +231,9 @@ export type InternalOptions<TSource, TContext, TArgs> = {
219231
*
220232
* Based on: https://github.com/request/request#requestoptions-callback
221233
*/
222-
requestOptions?: Partial<RequestOptions<TSource, TContext, TArgs>>
234+
requestOptions?:
235+
| Partial<RequestOptions<TSource, TContext, TArgs>>
236+
| RequestOptionsFunction<TSource, TContext, TArgs>
223237

224238
/**
225239
* Allows to override or add options to the PubSub connect object used to make

0 commit comments

Comments
 (0)