Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ability to specify an array in expectedResponseContentType #48

Merged
merged 2 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type ProxyHeadersFunction = (
type: ControllerType,
) => IncomingHttpHeaders;
type ProxyHeaders = string[] | ProxyHeadersFunction;
type ResponseContentType = AxiosResponse['headers']['Content-Type'];

interface GatewayConfig {
// Gateway Installation (external/internal/...). If the configuration is not provided, it is determined from process.env.APP_INSTALLATION.
Expand Down Expand Up @@ -119,7 +120,7 @@ interface GatewayConfig {
// Configuration for automatic connection re-establishment upon connection error through L3 load balancer (default is true).
grpcRecreateService?: boolean;
// Enable verification of response contentType header. Actual only for REST actions. This value can be set / redefined the in action confg.
expectedResponseContentType?: AxiosResponse['headers']['Content-Type'];
expectedResponseContentType?: ResponseContentType | ResponseContentType[];
}
```

Expand Down
51 changes: 30 additions & 21 deletions lib/components/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,29 +305,38 @@ export default function createRestAction<Context extends GatewayContext>(
const expectedResponseContentType =
config.expectedResponseContentType || options.expectedResponseContentType;

if (
actualResponseContentType &&
expectedResponseContentType &&
actualResponseContentType !== expectedResponseContentType
) {
ctx.log('Invalid response content type', {
expectedResponseContentType,
actualResponseContentType,
});
ctx.end();
if (actualResponseContentType && expectedResponseContentType) {
let isInvalidResponseContentType;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might have been look a little simpler if you've checked for valid response content type instead of invalid (since not- checks are harder to read than positive ones).

i.e.

isValidResponseContentType = false

isValidResponseContentType = expectedResponseContentType.includes(String(actualResponseContentType));

isValidResponseContentType = expectedResponseContentType === actualResponseContentType


return Promise.reject({
error: {
status: 415,
message: 'Response content type validation failed',
code: 'INVALID_RESPONSE_CONTENT_TYPE',
details: {
title: 'Invalid response content type',
description: `Expected to get ${expectedResponseContentType} but got ${actualResponseContentType}`,
if (Array.isArray(expectedResponseContentType)) {
isInvalidResponseContentType = !expectedResponseContentType.includes(
String(actualResponseContentType),
);
} else {
isInvalidResponseContentType =
expectedResponseContentType !== actualResponseContentType;
}

if (isInvalidResponseContentType) {
ctx.log('Invalid response content type', {
expectedResponseContentType,
actualResponseContentType,
});
ctx.end();

return Promise.reject({
error: {
status: 415,
message: 'Response content type validation failed',
code: 'INVALID_RESPONSE_CONTENT_TYPE',
details: {
title: 'Invalid response content type',
description: `Expected to get ${expectedResponseContentType} but got ${actualResponseContentType}`,
},
},
},
debugHeaders,
});
debugHeaders,
});
}
}

if (config.transformResponseData) {
Expand Down
6 changes: 4 additions & 2 deletions lib/models/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ export type GetAuthHeaders<AuthArgs = Record<string, unknown>> = (
params: GetAuthHeadersParams<AuthArgs>,
) => Record<string, string> | undefined;

export type ResponseContentType = AxiosResponse['headers']['Content-Type'];

export interface GatewayApiOptions<Context extends GatewayContext> {
serviceName: string;
timeout?: number;
Expand All @@ -110,7 +112,7 @@ export interface GatewayApiOptions<Context extends GatewayContext> {
proxyHeaders?: ProxyHeaders;
validationSchema?: object;
encodePathArgs?: boolean;
expectedResponseContentType?: AxiosResponse['headers']['Content-Type'];
expectedResponseContentType?: ResponseContentType | ResponseContentType[];
getAuthHeaders: GetAuthHeaders;
}

Expand Down Expand Up @@ -176,7 +178,7 @@ export interface ApiServiceRestActionConfig<
path: (args: TParams) => string;
paramsSerializer?: AxiosRequestConfig['paramsSerializer'];
responseType?: AxiosRequestConfig['responseType'];
expectedResponseContentType?: AxiosResponse['headers']['Content-Type'];
expectedResponseContentType?: ResponseContentType | ResponseContentType[];
maxRedirects?: number;
}

Expand Down
Loading