Skip to content

Commit

Permalink
Merge pull request #734 from microsoft/feature/response-handler
Browse files Browse the repository at this point in the history
feature/response handler
  • Loading branch information
baywet authored Jul 4, 2023
2 parents 8ef08b2 + cb1e3f8 commit 798a589
Show file tree
Hide file tree
Showing 353 changed files with 2,961 additions and 3,897 deletions.
4 changes: 1 addition & 3 deletions lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
"packages/sample-app",
"packages/abstractions",
"packages/http/*",
"packages/serialization/form/",
"packages/serialization/json/",
"packages/serialization/text/",
"packages/serialization/*",
"packages/authentication/*"
],
"npmClient": "yarn",
Expand Down
2 changes: 1 addition & 1 deletion packages/abstractions/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-abstractions",
"version": "1.0.0-preview.20",
"version": "1.0.0-preview.21",
"description": "Core abstractions for kiota generated libraries in TypeScript and JavaScript",
"main": "dist/cjs/src/index.js",
"module": "dist/es/src/index.js",
Expand Down
1 change: 1 addition & 0 deletions packages/abstractions/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export * from "./serialization";
export * from "./store";
export * from "./timeOnly";
export * from "./utils";
export * from "./responseHandlerOptions";
11 changes: 0 additions & 11 deletions packages/abstractions/src/requestAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { RequestInformation } from "./requestInformation";
import { ResponseHandler } from "./responseHandler";
import {
Parsable,
ParsableFactory,
Expand All @@ -17,7 +16,6 @@ export interface RequestAdapter {
/**
* Executes the HTTP request specified by the given RequestInformation and returns the deserialized response model.
* @param requestInfo the request info to execute.
* @param responseHandler The response handler to use for the HTTP request instead of the default handler.
* @param errorMappings the error factories mapping to use in case of a failed request.
* @param type the class of the response model to deserialize the response into.
* @typeParam ModelType the type of the response model to deserialize the response into.
Expand All @@ -26,13 +24,11 @@ export interface RequestAdapter {
sendAsync<ModelType extends Parsable>(
requestInfo: RequestInformation,
type: ParsableFactory<ModelType>,
responseHandler: ResponseHandler | undefined,
errorMappings: Record<string, ParsableFactory<Parsable>> | undefined
): Promise<ModelType | undefined>;
/**
* Executes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection.
* @param requestInfo the request info to execute.
* @param responseHandler The response handler to use for the HTTP request instead of the default handler.
* @param errorMappings the error factories mapping to use in case of a failed request.
* @param type the class of the response model to deserialize the response into.
* @typeParam ModelType the type of the response model to deserialize the response into.
Expand All @@ -41,14 +37,12 @@ export interface RequestAdapter {
sendCollectionAsync<ModelType extends Parsable>(
requestInfo: RequestInformation,
type: ParsableFactory<ModelType>,
responseHandler: ResponseHandler | undefined,
errorMappings: Record<string, ParsableFactory<Parsable>> | undefined
): Promise<ModelType[] | undefined>;
/**
* Executes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection.
* @param requestInfo the request info to execute.
* @param responseType the class of the response model to deserialize the response into.
* @param responseHandler The response handler to use for the HTTP request instead of the default handler.
* @param errorMappings the error factories mapping to use in case of a failed request.
* @param type the class of the response model to deserialize the response into.
* @typeParam ResponseType the type of the response model to deserialize the response into.
Expand All @@ -57,13 +51,11 @@ export interface RequestAdapter {
sendCollectionOfPrimitiveAsync<ResponseType>(
requestInfo: RequestInformation,
responseType: "string" | "number" | "boolean" | "Date",
responseHandler: ResponseHandler | undefined,
errorMappings: Record<string, ParsableFactory<Parsable>> | undefined
): Promise<ResponseType[] | undefined>;
/**
* Executes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model.
* @param requestInfo the request info to execute.
* @param responseHandler The response handler to use for the HTTP request instead of the default handler.
* @param errorMappings the error factories mapping to use in case of a failed request.
* @param responseType the class of the response model to deserialize the response into.
* @typeParam ResponseType the type of the response model to deserialize the response into.
Expand All @@ -72,19 +64,16 @@ export interface RequestAdapter {
sendPrimitiveAsync<ResponseType>(
requestInfo: RequestInformation,
responseType: "string" | "number" | "boolean" | "Date" | "ArrayBuffer",
responseHandler: ResponseHandler | undefined,
errorMappings: Record<string, ParsableFactory<Parsable>> | undefined
): Promise<ResponseType | undefined>;
/**
* Executes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model.
* @param requestInfo the request info to execute.
* @param responseHandler The response handler to use for the HTTP request instead of the default handler.
* @param errorMappings the error factories mapping to use in case of a failed request.
* @return a {@link Promise} of void.
*/
sendNoResponseContentAsync(
requestInfo: RequestInformation,
responseHandler: ResponseHandler | undefined,
errorMappings: Record<string, ParsableFactory<Parsable>> | undefined
): Promise<void>;
/**
Expand Down
27 changes: 27 additions & 0 deletions packages/abstractions/src/responseHandlerOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* -------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
* See License in the project root for license information.
* -------------------------------------------------------------------------------------------
*/

import { RequestOption } from "./requestOption";
import { ResponseHandler } from "./responseHandler";

export const ResponseHandlerOptionKey = "ResponseHandlerOptionKey";

/**
* @class
* @implements RequestOption
* Options to intercept the request from the main pipeline.
*/
export class ResponseHandlerOption implements RequestOption {
/**
* @public
* The response handler to be used when processing the response.
*/
public responseHandler?: ResponseHandler;
public getKey(): string {
return ResponseHandlerOptionKey;
}
}
4 changes: 2 additions & 2 deletions packages/authentication/azure/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-authentication-azure",
"version": "1.0.0-preview.15",
"version": "1.0.0-preview.16",
"description": "Authentication provider for Kiota using Azure Identity",
"main": "dist/cjs/src/index.js",
"module": "dist/es/src/index.js",
Expand Down Expand Up @@ -30,7 +30,7 @@
"homepage": "https://github.com/microsoft/kiota-typescript#readme",
"dependencies": {
"@azure/core-auth": "^1.3.2",
"@microsoft/kiota-abstractions": "^1.0.0-preview.20",
"@microsoft/kiota-abstractions": "^1.0.0-preview.21",
"@opentelemetry/api": "^1.2.0",
"tslib": "^2.3.1"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/authentication/spfx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-authentication-spfx",
"version": "1.0.0-preview.10",
"version": "1.0.0-preview.11",
"description": "Authentication provider for using Kiota in SPFx solutions",
"main": "dist/cjs/src/index.js",
"module": "dist/es/src/index.js",
Expand Down Expand Up @@ -39,7 +39,7 @@
},
"homepage": "https://github.com/microsoft/kiota-typescript#readme",
"dependencies": {
"@microsoft/kiota-abstractions": "^1.0.0-preview.20",
"@microsoft/kiota-abstractions": "^1.0.0-preview.21",
"@microsoft/sp-http": "^1.15.2",
"@opentelemetry/api": "^1.2.0",
"tslib": "^2.3.1"
Expand Down
4 changes: 2 additions & 2 deletions packages/http/fetch/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-http-fetchlibrary",
"version": "1.0.0-preview.19",
"version": "1.0.0-preview.20",
"description": "Kiota request adapter implementation with fetch",
"keywords": [
"Kiota",
Expand Down Expand Up @@ -38,7 +38,7 @@
"test:cjs": "mocha 'dist/cjs/test/common/**/*.js' && mocha 'dist/cjs/test/node/**/*.js'"
},
"dependencies": {
"@microsoft/kiota-abstractions": "^1.0.0-preview.20",
"@microsoft/kiota-abstractions": "^1.0.0-preview.21",
"@opentelemetry/api": "^1.2.0",
"node-fetch": "^2.6.5",
"tslib": "^2.3.1"
Expand Down
22 changes: 16 additions & 6 deletions packages/http/fetch/src/fetchRequestAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ApiError, AuthenticationProvider, BackingStoreFactory, BackingStoreFactorySingleton, DateOnly, Duration, enableBackingStoreForParseNodeFactory, enableBackingStoreForSerializationWriterFactory, Parsable, ParsableFactory, ParseNode, ParseNodeFactory, ParseNodeFactoryRegistry, RequestAdapter, RequestInformation, ResponseHandler, SerializationWriterFactory, SerializationWriterFactoryRegistry, TimeOnly } from "@microsoft/kiota-abstractions";
import { ApiError, AuthenticationProvider, BackingStoreFactory, BackingStoreFactorySingleton, DateOnly, Duration, enableBackingStoreForParseNodeFactory, enableBackingStoreForSerializationWriterFactory, Parsable, ParsableFactory, ParseNode, ParseNodeFactory, ParseNodeFactoryRegistry, RequestAdapter, RequestInformation, ResponseHandler, ResponseHandlerOption, ResponseHandlerOptionKey, SerializationWriterFactory, SerializationWriterFactoryRegistry, TimeOnly } from "@microsoft/kiota-abstractions";
import { Span, SpanStatusCode, trace } from "@opentelemetry/api";

import { HttpClient } from "./httpClient";
Expand Down Expand Up @@ -45,14 +45,20 @@ export class FetchRequestAdapter implements RequestAdapter {
if (segments.length === 0) return undefined;
else return segments[0];
};
private getResponseHandler = (response: RequestInformation): ResponseHandler | undefined => {
const options = response.getRequestOptions();
const responseHandlerOption = options[ResponseHandlerOptionKey] as ResponseHandlerOption;
return responseHandlerOption?.responseHandler;
};
private static readonly responseTypeAttributeKey = "com.microsoft.kiota.response.type";
public sendCollectionOfPrimitiveAsync = <ResponseType>(requestInfo: RequestInformation, responseType: "string" | "number" | "boolean" | "Date", responseHandler: ResponseHandler | undefined, errorMappings: Record<string, ParsableFactory<Parsable>> | undefined): Promise<ResponseType[] | undefined> => {
public sendCollectionOfPrimitiveAsync = <ResponseType>(requestInfo: RequestInformation, responseType: "string" | "number" | "boolean" | "Date", errorMappings: Record<string, ParsableFactory<Parsable>> | undefined): Promise<ResponseType[] | undefined> => {
if (!requestInfo) {
throw new Error("requestInfo cannot be null");
}
return this.startTracingSpan(requestInfo, "sendCollectionOfPrimitiveAsync", async (span) => {
try {
const response = await this.getHttpResponseMessage(requestInfo, span);
const responseHandler = this.getResponseHandler(requestInfo);
if (responseHandler) {
span.addEvent(FetchRequestAdapter.eventResponseHandlerInvokedKey);
return await responseHandler.handleResponseAsync(response, errorMappings);
Expand Down Expand Up @@ -101,13 +107,14 @@ export class FetchRequestAdapter implements RequestAdapter {
}
});
};
public sendCollectionAsync = <ModelType extends Parsable>(requestInfo: RequestInformation, deserialization: ParsableFactory<ModelType>, responseHandler: ResponseHandler | undefined, errorMappings: Record<string, ParsableFactory<Parsable>> | undefined): Promise<ModelType[] | undefined> => {
public sendCollectionAsync = <ModelType extends Parsable>(requestInfo: RequestInformation, deserialization: ParsableFactory<ModelType>, errorMappings: Record<string, ParsableFactory<Parsable>> | undefined): Promise<ModelType[] | undefined> => {
if (!requestInfo) {
throw new Error("requestInfo cannot be null");
}
return this.startTracingSpan(requestInfo, "sendCollectionAsync", async (span) => {
try {
const response = await this.getHttpResponseMessage(requestInfo, span);
const responseHandler = this.getResponseHandler(requestInfo);
if (responseHandler) {
span.addEvent(FetchRequestAdapter.eventResponseHandlerInvokedKey);
return await responseHandler.handleResponseAsync(response, errorMappings);
Expand Down Expand Up @@ -147,13 +154,14 @@ export class FetchRequestAdapter implements RequestAdapter {
});
};
public static readonly eventResponseHandlerInvokedKey = "com.microsoft.kiota.response_handler_invoked";
public sendAsync = <ModelType extends Parsable>(requestInfo: RequestInformation, deserializer: ParsableFactory<ModelType>, responseHandler: ResponseHandler | undefined, errorMappings: Record<string, ParsableFactory<Parsable>> | undefined): Promise<ModelType | undefined> => {
public sendAsync = <ModelType extends Parsable>(requestInfo: RequestInformation, deserializer: ParsableFactory<ModelType>, errorMappings: Record<string, ParsableFactory<Parsable>> | undefined): Promise<ModelType | undefined> => {
if (!requestInfo) {
throw new Error("requestInfo cannot be null");
}
return this.startTracingSpan(requestInfo, "sendAsync", async (span) => {
try {
const response = await this.getHttpResponseMessage(requestInfo, span);
const responseHandler = this.getResponseHandler(requestInfo);
if (responseHandler) {
span.addEvent(FetchRequestAdapter.eventResponseHandlerInvokedKey);
return await responseHandler.handleResponseAsync(response, errorMappings);
Expand All @@ -180,13 +188,14 @@ export class FetchRequestAdapter implements RequestAdapter {
}
}) as Promise<ModelType>;
};
public sendPrimitiveAsync = <ResponseType>(requestInfo: RequestInformation, responseType: "string" | "number" | "boolean" | "Date" | "ArrayBuffer", responseHandler: ResponseHandler | undefined, errorMappings: Record<string, ParsableFactory<Parsable>> | undefined): Promise<ResponseType | undefined> => {
public sendPrimitiveAsync = <ResponseType>(requestInfo: RequestInformation, responseType: "string" | "number" | "boolean" | "Date" | "ArrayBuffer", errorMappings: Record<string, ParsableFactory<Parsable>> | undefined): Promise<ResponseType | undefined> => {
if (!requestInfo) {
throw new Error("requestInfo cannot be null");
}
return this.startTracingSpan(requestInfo, "sendPrimitiveAsync", async (span) => {
try {
const response = await this.getHttpResponseMessage(requestInfo, span);
const responseHandler = this.getResponseHandler(requestInfo);
if (responseHandler) {
span.addEvent(FetchRequestAdapter.eventResponseHandlerInvokedKey);
return await responseHandler.handleResponseAsync(response, errorMappings);
Expand Down Expand Up @@ -241,13 +250,14 @@ export class FetchRequestAdapter implements RequestAdapter {
}
}) as Promise<ResponseType>;
};
public sendNoResponseContentAsync = (requestInfo: RequestInformation, responseHandler: ResponseHandler | undefined, errorMappings: Record<string, ParsableFactory<Parsable>> | undefined): Promise<void> => {
public sendNoResponseContentAsync = (requestInfo: RequestInformation, errorMappings: Record<string, ParsableFactory<Parsable>> | undefined): Promise<void> => {
if (!requestInfo) {
throw new Error("requestInfo cannot be null");
}
return this.startTracingSpan(requestInfo, "sendNoResponseContentAsync", async (span) => {
try {
const response = await this.getHttpResponseMessage(requestInfo, span);
const responseHandler = this.getResponseHandler(requestInfo);
if (responseHandler) {
span.addEvent(FetchRequestAdapter.eventResponseHandlerInvokedKey);
return await responseHandler.handleResponseAsync(response, errorMappings);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const RetryHandlerOptionKey = "RetryHandlerOptionKey";

/**
* @class
* @implements Middleware
* @implements RequestOption
* Options
* Class for RetryHandlerOptions
*/
Expand Down
12 changes: 6 additions & 6 deletions packages/http/fetch/test/common/fetchRequestAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe("FetchRequestAdapter.ts", () => {
const requestInformation = new RequestInformation();
requestInformation.URL = "https://www.example.com";
requestInformation.httpMethod = HttpMethod.GET;
await requestAdapter.sendNoResponseContentAsync(requestInformation, undefined, undefined);
await requestAdapter.sendNoResponseContentAsync(requestInformation, undefined);
assert.equal(executeFetchCount, 2);
});
});
Expand All @@ -59,7 +59,7 @@ describe("FetchRequestAdapter.ts", () => {
const requestInformation = new RequestInformation();
requestInformation.URL = "https://www.example.com";
requestInformation.httpMethod = HttpMethod.GET;
const result = await requestAdapter.sendPrimitiveAsync(requestInformation, "ArrayBuffer", undefined, undefined);
const result = await requestAdapter.sendPrimitiveAsync(requestInformation, "ArrayBuffer", undefined);
assert.isDefined(result);
});
}
Expand All @@ -78,7 +78,7 @@ describe("FetchRequestAdapter.ts", () => {
const requestInformation = new RequestInformation();
requestInformation.URL = "https://www.example.com";
requestInformation.httpMethod = HttpMethod.GET;
const result = await requestAdapter.sendPrimitiveAsync(requestInformation, "ArrayBuffer", undefined, undefined);
const result = await requestAdapter.sendPrimitiveAsync(requestInformation, "ArrayBuffer", undefined);
assert.isUndefined(result);
});
}
Expand All @@ -97,7 +97,7 @@ describe("FetchRequestAdapter.ts", () => {
const requestInformation = new RequestInformation();
requestInformation.URL = "https://www.example.com";
requestInformation.httpMethod = HttpMethod.GET;
const result = await requestAdapter.sendAsync(requestInformation, createMockEntityFromDiscriminatorValue, undefined, undefined);
const result = await requestAdapter.sendAsync(requestInformation, createMockEntityFromDiscriminatorValue, undefined);
assert.isUndefined(result);
});
}
Expand All @@ -118,7 +118,7 @@ describe("FetchRequestAdapter.ts", () => {
const requestInformation = new RequestInformation();
requestInformation.URL = "https://www.example.com";
requestInformation.httpMethod = HttpMethod.GET;
const result = await requestAdapter.sendAsync(requestInformation, createMockEntityFromDiscriminatorValue, undefined, undefined);
const result = await requestAdapter.sendAsync(requestInformation, createMockEntityFromDiscriminatorValue, undefined);
assert.isDefined(result);
});
}
Expand All @@ -139,7 +139,7 @@ describe("FetchRequestAdapter.ts", () => {
requestInformation.httpMethod = HttpMethod.GET;

try {
await requestAdapter.sendNoResponseContentAsync(requestInformation, undefined, undefined);
await requestAdapter.sendNoResponseContentAsync(requestInformation, undefined);
assert.fail("Should have thrown an error");
} catch (error) {
assert.equal(error.responseStatusCode, 500);
Expand Down
4 changes: 2 additions & 2 deletions packages/serialization/form/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-serialization-form",
"version": "1.0.0-preview.9",
"version": "1.0.0-preview.10",
"description": "Implementation of Kiota Serialization interfaces for URI from encoded",
"main": "dist/cjs/src/index.js",
"browser": {
Expand Down Expand Up @@ -39,7 +39,7 @@
},
"homepage": "https://github.com/microsoft/kiota-typescript#readme",
"dependencies": {
"@microsoft/kiota-abstractions": "^1.0.0-preview.20",
"@microsoft/kiota-abstractions": "^1.0.0-preview.21",
"tslib": "^2.3.1"
},
"publishConfig": {
Expand Down
4 changes: 2 additions & 2 deletions packages/serialization/json/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-serialization-json",
"version": "1.0.0-preview.18",
"version": "1.0.0-preview.19",
"description": "Implementation of Kiota Serialization interfaces for JSON",
"main": "dist/cjs/src/index.js",
"browser": {
Expand Down Expand Up @@ -39,7 +39,7 @@
},
"homepage": "https://github.com/microsoft/kiota-typescript#readme",
"dependencies": {
"@microsoft/kiota-abstractions": "^1.0.0-preview.20",
"@microsoft/kiota-abstractions": "^1.0.0-preview.21",
"tslib": "^2.3.1"
},
"publishConfig": {
Expand Down
4 changes: 2 additions & 2 deletions packages/serialization/text/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/kiota-serialization-text",
"version": "1.0.0-preview.17",
"version": "1.0.0-preview.18",
"description": "Implementation of Kiota Serialization interfaces for text",
"main": "dist/cjs/src/index.js",
"browser": {
Expand Down Expand Up @@ -39,7 +39,7 @@
},
"homepage": "https://github.com/microsoft/kiota-typescript#readme",
"dependencies": {
"@microsoft/kiota-abstractions": "^1.0.0-preview.20",
"@microsoft/kiota-abstractions": "^1.0.0-preview.21",
"tslib": "^2.3.1"
},
"publishConfig": {
Expand Down
Loading

0 comments on commit 798a589

Please sign in to comment.