次の方法で共有


チェーン データ アクション

この記事は、データ アクションのチェーン方法について説明します。

保守的で複雑なコードベースを作成するには、多くの場合、お互いを容易に使用して、より複雑なコード フローを作成するための一式の可読可能なデータ アクションが必要です。 Microsoft Dynamics 365 Commerce オンライン ソフトウェア開発キット (SDK) を使用すると、データ アクションをシームレスにチェーンすることができますが、データ アクション アーキテクチャ (キャッシュ、バッチ処理、および重複複製) の機能は完全に使用可能です。

次の例では、データ アクション チェーンを示します。 まず、製品情報の呼び出しが行われたとします。 この通話の後に在庫呼び出しが行されます。

最初の例は、製品情報を取得するデータ アクションを示しています。

// get-product.ts
import { IAction, IActionInput } from '@msdyn365-commerce/action';
import { SimpleProduct } from '@msdyn365-commerce/commerce-entities';
import { CommerceEntityInput, createObservableDataAction, IAny, ICreateActionContext, IActionContext, IGeneric, IHTTPError, IHTTPResponse, sendCommerceRequest } from '@msdyn365-commerce/core';
import { ProductInput } from './inputs/product-input';

/**
 * Product Action Input Class
 * This class is used by our Action Function, so that it has access to a productId
 */
export class ProductInput implements IActionInput {
    public channelId: number;
    public productId: number;
    constructor(productId: number, channelId: number) {
        this.channelId = channelId;
        this.productId = productId;
    }
    public getCacheKey = () => `${this.channelId}-${this.productId}`;
    public getCacheObjectType = () => 'Product';
    public dataCacheType = (): Msdyn365.CacheType => 'application';
}

/**
 * Action Function which calls the Retail API and returns the product based on the passed ProductInputs productId
 */
async function getSimpleProductAction(input: ProductInput, ctx: IActionContext): Promise<SimpleProduct> {
    const { apiSettings } = ctx.requestContext;

    // Construct our HTTP request using information available in actionContext (ctx), and our Action Input (input)
    const requestUrl = `${apiSettings.baseUrl}/Products/${input.productId}`;

    // Make the HTTP Request
    return sendCommerceRequest<SimpleProduct>(requestUrl, 'get'})
        .then((response: IHTTPResponse) => {
            if(response.data) {
                return response.data;
            }
            ctx.trace('[getSimpleProductAction] Invalid response from server');
            return <SimpleProduct>[];
        })
        .catch((error: IHTTPError) => {
            ctx.trace(error.message);
            ctx.trace(error.stack || '');
            ctx.trace(`Unable to Fetch Product.`);
            return <SimpleProduct>{};
        });
}

/**
 * This exports the action Data Action, which the result of passing your action method and createInput method (if used)
 * to the createDataAction method.
 */
export default createObservableDataAction({
    action: <IAction<SimpleProduct>>getSimpleProductAction
});

次の例では、在庫情報を取得するデータ アクションを示しています。

// check-inventory.ts
import { IAction, IActionInput } from '@msdyn365-commerce/action';
import { ProductAvailableQuantity } from '@msdyn365-commerce/commerce-entities';
import { createObservableDataAction, IAny, IActionContext, IGeneric, IHTTPError, IHTTPResponse, sendCommerceRequest } from '@msdyn365-commerce/core';

// Because this API also only needs a productId, we can re-use the ProductInput we created earlier here.
import { ProductInput } from './get-product.ts';

/**
 * Calls the Retail API and returns the Availability information for the passed Product
 */
async function getProductAvailabilityAction(input: ProductInput, ctx: IActionContext): Promise<ProductAvailableQuantity> {
    const { apiSettings } = ctx.requestContext;

    // Construct our HTTP request using information available in actionContext (ctx), and our Action Input (input)
    const requestUrl = `${apiSettings.baseUrl}/Products/GetProductAvailabilities`;
    const requestBody = {
        productId: input.productId;
    }

    // Make the HTTP Call and handle the response
    return sendCommerceRequest<ProductAvailableQuantity>(requestUrl, 'post', requestBody)
        .then((response: IHTTPResponse) => {
            if(response.data) {
                return response.data;
            }
            ctx.trace('[getProductAvailabilityAction] Invalid response from server');
            return <ProductAvailableQuantity>[];
        })
        .catch((error: IHTTPError) => {
            ctx.trace(error.message);
            ctx.trace(error.stack || '');
            ctx.trace(`Unable to Fetch Product Availability.`);
            return <ProductAvailableQuantity>{};
        });
}

export default createObservableDataAction({
    action: getProductAvailabilityAction
})

これで、製品データと ProductAvailableQuantity の値を取得するアクションが作成され、新しいチェーン データ アクションを作成できます。 チェーン データ アクションは、実行の一環として他のデータ アクションを呼び出すデータ アクションに限っています。

次の例では、getProductWithAvailability チェーン データ アクションが表示され、前のアクションの両方とも使用されます。

import getProduct, { ProductInput } from './get-product';
import getProductAvailability from './check-inventory';

/**
 * This interface will be the return type of our chain data action.
 * This contains both the basic product information in addition to the product's availability information.
 */
export interface SimpleProductWithAvailablility extends SimpleProduct {
    availability: ProductAvailableQuantity
}

/**
 * Calls the Retail API and returns the Availability information for the passed Product
 */
async function getProductWithAvailabilityAction(input: ProductInput, ctx: IActionContext): Promise<SimpleProductWithAvailablility> {
    // First we get the product
    const product: SimpleProductWithAvailablility = await <SimpleProductWithAvailablility>getProduct(input, ctx);

    // If we successfully get the product, then we try to get its availability information.
    if(product) {
        // Get the availability information
        product.availability = await getProductAvailability(input, ctx)
    } else {
        return <SimpleProductWithAvailablility>{};
    }
}

export default createObservableDataAction({
    action: getProductWithAvailabilityAction
})

これで、基本製品情報と現在の製品在庫ステータスの両方が必要な場合に、新しいチェーン データ アクションを使用できます。 さらに、チェーン データ アクションに存在する呼び出しは引き続きキャッシュを介して実行されます。 また、同じページで実行される他のアクションと共に、バッチ処理と重複排除も行います。

追加リソース

バッチ データ アクション

監視可能なデータ アクションの作成

モジュール間での状態の共有

データ アクション キャッシュの設定

データ アクションの上書き

データ アクションのフック