---
schema_version: "1"
id: fd8cc9a8c83a7884a5daca92a43233f18acee25377b1bb9311388b6cf2f59780
title: Rust でのカスタムポリシー機能の実装
collection: mulesoft
version: current
locale: ja-jp
portal_url: https://docs.salesforce.com/mulesoft/current/ja-jp/pdk/1.3/policies-pdk-configure-features.md
canonical_url: https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 22d3f28b4e2d16a325387c4f97f47ea00149394fd4a5ab0a2ca9874210a276f9
description: MuleSoft Documentation Site
release: "1.3"
latest: false
---
# Rust でのカスタムポリシー機能の実装

以降のページでは、さまざまなポリシータスクを完了するための Rust コード例を示します。ポリシーの Rust コードは ​`src/lib.rs`​ ファイルで実装します。

コード例は、Rust プログラミング言語に関する基礎知識があることを前提としています。Rust のプログラミングに関する詳細は、以下を参照してください。

- [Rust プログラミング言語ドキュメント](https://doc.rust-lang.org/book/)
- [Rust クックブック](https://rust-lang-nursery.github.io/rust-cookbook/intro.html)

## [](#始める前に)始める前に

- [新規プロジェクトを作成する](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-create-project)
- [スキーマの定義](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-create-schema-definition)
    
    <table><tbody><tr><td class="icon"><i class="fa icon-note" title="Note"></i></td><td class="content">ポリシーを実装する際に、設定パラメーターの追加または再定義が必要になる場合もあります。</td></tr></tbody></table>
- [追加のポリシー機能](#provided-rust-source-code)​を定義する前に、「​[ポリシーテンプレート](#policy-template)​」、「​[ラップされた関数](#wrapped-functions)​」、「​[フローのキャンセル](#flow-cancellation)​」でポリシーのソースコード構造について確認してください。

## [](#policy-template)ポリシーテンプレート

Flex Gateway ポリシー開発キット (PDK) には、ポリシーの実装を開始するためのテンプレートとして、ポリシープロジェクトの最初の ​`src/lib.rs`​ ファイルが用意されています。

```Rust
// Copyright 2024 Salesforce, Inc. All rights reserved.
mod generated;

use anyhow::{anyhow, Result};

use pdk::hl::*;
use pdk::logger;

use crate::generated::config::Config;

// This filter shows how to log a specific request header.
// You can extend the function and use the configurations exposed in config.rs file
async fn request_filter(request_state: RequestState, _config: &Config) {
    let headers_state = request_state.into_headers_state().await;
    let token = headers_state.handler().header("Token").unwrap_or_default();
    // Log the header value
    logger::info!("Header value: {token}");
}

#[entrypoint]
async fn configure(launcher: Launcher, Configuration(bytes): Configuration) -> Result<()> {
    let config: Config = serde_json::from_slice(&bytes).map_err(|err| {
        anyhow!(
            "Failed to parse configuration '{}'. Cause: {}",
            String::from_utf8_lossy(&bytes),
            err
        )
    })?;
    let filter = on_request(|rs| request_filter(rs, &config));
    launcher.launch(filter).await?;
    Ok(())
}
```

ポリシーは簡単なログを実行します。受信した要求ごとに、ポリシーは ​`INFO`​ ログレベルでヘッダー​`トークン`​を記録します。

以下の要素でポリシーを設定します。

- `use pdk::api::hl::*;`​: PDK のすべてのコンポーネントを ​`lib.rs`​ ソースコードにインポートします。
- `#[entrypoint]`​ 関数: ポリシーが適用されたときに実行され、​`request_filter`​ 関数を呼び出します。この関数の内部で定義された変数は、ポリシーが適用されている間は有効です。
    
    `#[entrypoint]`​ 関数は、以下のパラメーターを受け取ります。
    
    - `Launcher`​: 検索条件関数を設定します。
    - `Configuration`​: [policy-pdk-create-schema-definition.adoc](#policy-pdk-create-schema-definition.adoc)で定義されている設定パラメーターを提供します。
- `request_filter`​: ポリシーが適用される API インスタンスに送信される要求ごとに 1 回実行されます。この関数は、ポリシー例で実行される検索条件を実装します。この関数の中で定義されている変数は、要求の実行中に利用できます。
    
    `request_filter`​ は、ラップされた関数の例です。
    
    `#[entrypoint]`​ 関数はラップされた関数を実行します。
    
    ```Rust
    let filter = on_request(|rs| request_filter(rs, &config));
    launcher.launch(filter).await?;
    ```

## [](#wrapped-functions)ラップされた関数

`on_response`​ または ​`on_request`​ ラッパーは、検索条件関数が実行されるタイミングを定義します。

`#[entrypoint]`​ 関数では、提供されている ​`requests_filter`​ と ​`response_filter`​ 以外のカスタム関数を定義することができます。​`requests_filter`​ と ​`response_filter`​ は例に過ぎません。

前の例で示したように、受信要求を絞り込む代わりに、​`on_response`​ ラッパーを使用して送信応答を処理することができます。

```Rust
async fn response_filter(response_state: ResponseState, _config: &Config) {
    ...
}

#[entrypoint]
async fn configure(launcher: Launcher, Configuration(bytes): Configuration) -> Result<()> {
    let config: Config = serde_json::from_slice(&bytes).map_err(|err| {
        anyhow!(
            "Failed to parse configuration '{}'. Cause: {}",
            String::from_utf8_lossy(&bytes),
            err
        )
    })?;
    let filter = on_response(|rs| response_filter(rs, &config));
    launcher.launch(filter).await?;
    Ok(())
}
```

<table><tbody><tr><td class="icon"><i class="fa icon-note" title="Note"></i></td><td class="content"><code>request_filter</code>​ 関数は ​<code>response_filter</code>​ 関数になりました。</td></tr></tbody></table>

要求と応答の両方を絞り込むには、両方のラッパーを使用します。

```Rust
async fn request_filter(request_state: RequestState,_config: &Config) {
    ...
}

async fn response_filter(response_state: ResponseState,_config: &Config) {
    ...
}

#[entrypoint]
async fn configure(launcher: Launcher, Configuration(bytes): Configuration) -> Result<()> {
    let config: Config = serde_json::from_slice(&bytes).map_err(|err| {
        anyhow!(
            "Failed to parse configuration '{}'. Cause: {}",
            String::from_utf8_lossy(&bytes),
            err
        )
    })?;
    let filter = on_request(|rs| request_filter(rs, &config))
    .on_response(|rs| response_filter(rs, &config));
    launcher.launch(filter).await?;
    Ok(())
}
```

## [](#flow-cancellation)フローのキャンセル

カスタムポリシーはシングルスレッド環境で実行されます。ただし、ラップされた関数 (​`非同期`​関数の ​`on_request`​ と ​`on_response`​) のすべてのセットは同時タスクとして実行されるため、単一ポリシーのインスタンスが複数の要求を同時に処理することになります。

この動作をサポートするために、すべての ​`.await`​ が潜在的なタスク中断ポイントとなります。​`.await`​ が呼び出されると、基盤となる非同期ランタイムは現在のタスクをしばらくスリープさせて、まだ完了していない別のタスクを目覚めさせることができます。非同期ランタイムはタスクをキャンセルすることができ、最後の ​`.await`​ 呼び出しの後にあるコードを実行することはありません。 `on_request`​ 関数と ​`on_response`​ 関数は、​`.await`​ 呼び出しが潜在的なキャンセルポイントであることを想定しています。

次のコード例に示すように、タスクキャンセルの最も一般的な状況は、要求関数がボディを待っている途中でアップストリームポリシーが応答を早期に返した場合です。

```Rust
// Request function for upstream policy
async fn upstream_request(state: RequestState) -> Response {
    Response::new(404)
}

// Request function for downstream policy
async fn downstream_request(state: RequestState) {

    // Request function will be cancelled after this .await point.
    let body_state = state.into_body_state().await;

    // Code here will never be executed
}
```

## [](#provided-rust-source-code)PDK の機能を体験するために用意されている Rust ソースコード

PDK では、以下のポリシー機能のコード例が用意されています。追加のポリシー機能を定義する前に、​[ポリシーテンプレート](#policy-template)​と​[ラップされた関数](#wrapped-functions)​を確認してください。

- [ポリシーログの設定](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-logging)
- [リクエストヘッダーとリクエストボディの読み取りと書き込み](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-headers)
- [パラメーターの挿入](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-inject-parameters)
- [HTTP コールの実行](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-http-request)
- [コントラクト検証ライブラリ関数の使用](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-contracts)
- [CORS ライブラリ関数の使用](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-cors)
- [JWT ライブラリ関数の使用](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-jwt)
- [DataWeave 式の使用](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-dataweave)
- [要求と応答でのデータの共有](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-share-data)
- [サードパーティライブラリの使用](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-libraries)
- [ワーカー間でのデータ共有とキャッシュの設定](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-caching)
- [ポリシーのメタデータへのアクセス](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-metadata)
- [ポリシー間のデータ共有](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-streamproperties)
- [要求認証情報へのアクセス](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-authentication)
- [遅延関数、周期関数、同期関数の設定](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-timer)
- [要求実行の停止](https://docs.mulesoft.com/jp/pdk/1.3/policies-pdk-configure-features-stop)