---
title: カスタム処理を利用して、APIに独自のバリデーションを実装する
description: カスタム処理とAPI前処理を使用して、APIに独自のバリデーション処理を実装する方法を解説します。この機能を利用すると、標準機能のみでは実現できない複雑な入力チェックを追加することができます。
---

カスタム処理とAPI前処理を使用して、APIに独自のバリデーション処理を実装する方法を解説します。
この機能を利用すると、標準機能のみでは実現できない複雑な入力チェックを追加できます。

今回は、POSTされたメールアドレスが特定のドメインと一致しなければエラーを返すバリデーション処理を実装します。

## 事前準備

### APIエンドポイントを作成する
まず、[エンドポイントの設定方法](/ja/docs/tutorials/configure-endpoint/)を参考にバリデーション処理を実装するAPIエンドポイントを作成します。
今回は「Default」のAPIに以下のエンドポイントを作成しました。

| 設定項目 | 設定       |             |
| :------- | :------- | :------- |
| パス | original_api/sample1 |             |
|  | 有効/無効 | 有効 |
| モデル | カテゴリー | 配信 |
|  | モデル | Magazine |
|  | オペレーション | Subscribe |

![Image from Gyazo](https://t.gyazo.com/teams/diverta/8db35933282272deaf2d5f3c8f4423a3.png)

## カスタム処理を作成する
バリデーション処理を記述するためのカスタム処理を用意します。

### カスタム処理の一覧画面を表示する  
メニューの[オペレーション] -> [カスタム処理] をクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/baddc3d7091c3a34bed2af152ec984ec.png)

### カスタム処理の編集画面を表示する 
カスタム処理一覧画面の右上の [追加] をクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/488c4ee6513ef4938e7d73c444b68905.png)

### タイトル・カテゴリを入力する
カスタム処理のタイトルとカテゴリを入力します。  
今回は下記のように入力しました。
- タイトル：/rcms-api/1/original_api/sample1
- カテゴリ：api
- 識別子：sample1_function

:::tip
同一カテゴリ内にタイトルが重複する処理を作成できないため、実装対象のエンドポイント名など、他と重複しないタイトルを命名してください。
:::

![Image from Gyazo](https://t.gyazo.com/teams/diverta/1259638440c9aac9e1c4d0bb068e6c84.png)
### カスタム処理を保存する  
一旦ここまでで保存します。
画面下部までスクロールし、[追加する] ボタンをクリックして保存します。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/1c2ff9f821fa872259c3f77feeac49a2.png)


## バリデーション処理を記述する
次に、バリデーション処理を記述します。

### カスタム処理編集画面を表示する 
サイドメニューより[オペレーション]を選択し、[カスタム処理]をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/baddc3d7091c3a34bed2af152ec984ec.png)

先ほど追加したカスタム処理のタイトルをクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/5e72d2a08f6e3323ca8cfb9859ce328e.png)

カスタム処理の編集画面に戻り、エディタ内にバリデーション処理を記述していきます。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/1bc957775ba45ef32fa7991c4cbd16de.png)

### エラー変数を初期化する
バリデーション結果を格納するための$errors変数を初期化します。  

| 変数名 | 型 | 説明|
| :--- | :--- | :--- |
|$errors |array |テキスト配列|

エディタに下記を記入します。

```smarty
{* $errors = [] *}
{assign_array var="errors" values=""}
```

![Image from Gyazo](https://t.gyazo.com/teams/diverta/8febf5f999d216ba78efa163a2eca9f1.png)

### バリデーション処理を実装する
ユーザーの入力値をチェックし、errors変数に結果を代入します。  
入力値を参照するためには、下記のいずれかの変数を利用します。

| 変数名 | 説明 |
| :--- | :--- |
|$smarty.get | クエリパラメータ |
|$smarty.post | JSON body |
|$smarty.request | クエリパラメータ & JSON body |

```smarty
{assign_array var="errors" values=""}

{* [例] POSTされたメールアドレスが特定のドメインと一致しなければエラーを返す *}
{if $smarty.post.email|strpos:'@example.com' === false}
  {* $errors = ["メールアドレスが不正です。"] *}
  {assign var="errors." value="メールアドレスが不正です。"}
{/if}
```

![Image from Gyazo](https://t.gyazo.com/teams/diverta/2f4832e20f4fd343cb4cb0c67c191e4f.png)

### 保存する
処理の記述が完了したら、[更新する] ボタンをクリックし保存してください。  
![Image from Gyazo](https://t.gyazo.com/teams/diverta/cdd128a4f2f5cafbb30306da8b4ee7de.png)
## APIにカスタム処理を関連付ける
次に作成したカスタム処理をAPIに関連付けます。  

### API一覧画面を表示する
[API] ->[Default] をクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/a18960024a9f08e2b2cadf906b9d3fd7.png)

### エンドポイントを選択する
事前準備で作成したエンドポイント`/rcms-api/1/original_api/sample1`の[前処理]ボタンをクリックします。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/9cc61b8ff106fb3e961333fbaf2d3f5e.png)

テーブルの下に、「カテゴリ」と「一覧」プルダウンが表示されます。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/35eb8a3f0ed1176a8aeabd36216f5ff6.png)

### カスタム処理を関連付ける
カスタム処理の選択プルダウンが表示されます。  
先ほど作成しておいたカスタム処理のカテゴリとタイトルを選択します。

- カテゴリ：API
- 一覧：/rcms-api/1/original_api/sample1

![Image from Gyazo](https://t.gyazo.com/teams/diverta/de901fe59dd1cb005394c124eb116502.png)

## APIの動作を確認する
Swagger UI画面からリクエストを行い、バリデーション処理の動作を確認します。

### Swagger UI画面を表示する

API一覧画面より [Swagger UI] をクリックし、Swagger UI画面を表示します。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/7d703b484b76c1bc1256cd155f9fc2f0.png)

### エンドポイントを選択する
バリデーション処理を実装したエンドポイント`/rcms-api/1/original_api/sample1`を選択し、[Try it out] ボタンをクリックします。  

![Image from Gyazo](https://t.gyazo.com/teams/diverta/94a54257d064cd18157eb0f13aad1221.png)

### エラーが出力される値を入力する
`magazine_id`に`1`を入力し、バリデーション処理を確認するため、下記の通り、エラーが出力される値を[Request body]に入力します。

```json title="Request&#x20;body"
{
  "email": "test@test.com"
}
```

入力が完了したら、[Execute] ボタンをクリックし、リクエストを実行します。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/e5dbc1003c962886422334e65f90350a.png)

### レスポンスを確認する
APIのレスポンス内容を見て、想定通りのエラーが出力されることを確認します。

![Image from Gyazo](https://t.gyazo.com/teams/diverta/5d7bb3fbbd905fa9d79cd29af682b53c.png) 

```json [response]
{
  "errors": [
    {
      "code": "unprocessable_entity",
      "message": "メールアドレスが不正です。"
    }
  ],
  "x-rcms-request-id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxx"
}
```

以上でカスタム処理とAPIの関連付けが完了です。  

## バリデーションエラーが発生しない場合の確認ポイント
入力チェックが想定通りに行われない場合は、下記のポイントを確認してください。
- APIの前処理とカスタム処理が関連付いているか
- 関連付いているカスタム処理が正しいか
- 変数名(errors)が正しいか
- チェック対象の項目名が正しいか
- バリデーション処理のロジックが正しいか

## コード例の紹介
カスタム処理に利用できるコード例を紹介します。

### 特定の文字列を含むかどうかをチェックする

```smarty
{if $smarty.post.column_name|strpos:"期待する文字列" === false}
  {assign var="errors." value="column_nameが不正です。"}
{/if}
```
<br/>

### 数値かどうかをチェックする

```smarty
{if !$smarty.get.parameter_name|is_numeric}
  {assign var="errors." value="parameter_nameは数値で入力してください。"}
{/if}
```
<br/>

### 特定の項目に依存した入力チェックを行う

```smarty
{*
    [例] ext_col_01に1が入力された場合のみ、ext_col_02を必須項目とする
    ext_col_01: セレクト項目 ('', '1', '2')
    ext_col_02: テキスト項目
*}
{if $smarty.post.ext_col_01 === '1' || (
  !$smarty.post.ext_col_01|@empty &&
  $smarty.post.ext_col_01.key === '1'
)}
  {if !isset($smarty.post.ext_col_02) || $smarty.post.ext_col_02 === ''}
    {assign var="errors." value="テキスト項目は必須項目です。"}
  {/if}
{/if}
```
<br/>

### 特定のグループに所属するメンバーにのみ入力チェックを適用する

```smarty
{if $smarty.session.arrGroup_id|@is_array &&
  101|in_array:$smarty.session.arrGroup_id}
  {if !isset($smarty.post.column_name)}
    {assign var="errors." value="column_nameは必須項目です。"}
  {/if}
{/if}
```
<br/>


### エラー時にレスポンスコードを変更する場合
エラーチェックによってエラー応答する際に、APIのレスポンスコードを  
特定のエラーコードに変更してエラーレスポンスを行いたい場合は下記のように設定します。

```smarty
{assign var=http_code value=404}
```

#### 利用可能なHTTPコード

| コード | 名称 | 意味 |
|---|---|---|
| 400 | Bad Request | クライアントからのリクエストが不正 |
| 401 | Unauthorized | ユーザー認証が無い（未ログイン）ことによるリクエスト失敗 |
| 403 | Forbidden | コンテンツへのアクセス権が無いためにリクエスト失敗（401とは異なりユーザー認証は完了している） |
| 404 | Not Found | 指定されたエンドポイントのコンテンツが存在しないことによるリクエスト失敗 |
| 405 | Method Not Allowed | 許可されていないHTTPメソッドを使用した場合のエラー |
| 406 | Not Acceptable | リクエストの条件に合うレスポンスをサーバーが生成できない場合のエラー |
| 500 | Internal Server Error | クライアントからのリクエストは正しいが、サーバ側でエラーが発生した場合のエラー |

errorsにエラーメッセージを設定する方法と組み合わせることも可能です。  
設定例）

```smarty
{if `エラー判定処理`}
  {assign var=http_code value=404}
  {assign_array var=errors values=''}
  {assign var=errors. value='コンテンツが存在しません'}
{/if}
```

レスポンス例）
```json [response]
HTTP Respnese code: 404

Response body
{
  "errors": [
    {
      "code": "unprocessable_entity",
      "message": "コンテンツが存在しません"
    }
  ],
  "x-rcms-request-id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxx"
}
```