API Jsonリクエストでのnullについて

# API JSONリクエストにおけるnull値の扱い方

RESTful APIが広く普及した現在、APIへのリクエスト・レスポンスは`JSON`を用いることが一般的です。`JSON`は数値や文字列、真偽値などを簡潔に表現できる柔軟な形式ですが、実装時に悩ましい問題の一つが「null値の扱い方」です。

この記事では、JSONリクエストにおけるnull値の表現方法について考察していきます。

## リクエスト・レスポンスの例

まずは、典型的なJSONリクエストとレスポンスの例を見てみましょう。

```plantuml
@startuml
Client -> Application++ : JSON Request

note right 
{ 
    "id" : 1,
    "date" : "2023-11-07",
    "member" : true,
    "name" : "John doe",
    "option" : null
    }
end note

Application -> Client--: JSON Response
note left
{
    "update" : true
}
end note
@enduml
```

ここでは、以下のようなリクエストとレスポンスを考えることにします（特に要素に意味はありません）。

```json:request
{
    "id" : 1,
    "date" : "2023-11-07",
    "member" : true,
    "name" : "John doe",
    "option" : null
}
```

```json:response
{
    "update" : true
}
```

## Null値について

リクエストに含まれる`"option" : null`に注目してください。JSONでnull値を表現するには、主に2つの方法があります。

### 1. nullを明示的に指定する方法

```json:Option 1
{
    "id" : 1,
    "date" : "2023-11-07",
    "member" : true,
    "name" : "John doe",
    "option" : null
}
```

### 2. nullである要素はそもそも削除する方法

```json:Option 2
{
    "id" : 1,
    "date" : "2023-11-07",
    "member" : true,
    "name" : "John doe"
}
```

## どちらのアプローチが適切か？

大前提として、チーム内で既にルールが確立されているならば、それに従うことが最も重要です。その上で、両方のアプローチの利点を検討してみましょう。

### nullを明示的に指定する方法の利点

#### 1. 意図の明確さ

フィールドが存在するが値がないことを明示的に示せるため、「この項目は考慮したが値がない」という意図が明確に伝わります。

#### 2. 仕様準拠

[RFC8259](https://tex2e.github.io/rfc-translater/html/rfc8259.html)（JSON仕様）では、`null`は有効な値として明確に定義されています：

> 3.  Values
> A JSON value MUST be an object, array, number, or string, or one of the following three literal names:
> false
> null
> true

### nullである要素を省略する利点

#### 1. データ効率性

特に大規模なJSONオブジェクトでは、null値を持つフィールドを省略することで、データ転送量を大幅に削減できます。例えば、要素が多数あるリクエストにおいて、すべての要素を明示的に指定すると冗長になります：

```json
{
  "key1" : "hoge",
  "key2" : null,
  "key3" : "fuga",
  "key4" : null,
  "key5" : null,
  "key6" : null,
  "key7" : null,
  "key8" : null,
  "key9" : null,
  "key10" : null,
  "key11" : null,
  "key12" : null,
  "key13" : null,
  "key14" : null,
  ...
}
```

これに対して、null値を省略した場合はシンプルになります：

```json
{
  "key1" : "hoge",
  "key3" : "fuga"
}
```

#### 2. スタイルガイドの推奨

[Google JSON Style Guide](https://google.github.io/styleguide/jsoncstyleguide.xml#Empty/Null_Property_Values)では、以下のように推奨されています：

> Consider removing empty or null values. If a property is optional or has an empty or null value, consider dropping the property from the JSON, unless there's a strong semantic reason for its existence.
>
> （訳：空またはnullの値を削除することを検討してください。プロパティがオプションであるか、空またはnullの値を持つ場合、その存在に強い意味的理由がない限り、JSONからそのプロパティを削除することを検討してください。）

## 実装上の考慮点

実際の開発では、以下の点も考慮すると良いでしょう：

1. **一貫性の確保**: チーム内で統一したアプローチを採用することが最も重要です
2. **APIの仕様**: APIドキュメントで明確に定義し、クライアント側が適切に処理できるようにする
3. **バックエンドの処理**: SpringBootなどのフレームワークでは、`@JsonInclude(JsonInclude.Include.NON_NULL)`アノテーションを使用して、null値のフィールドを自動的に除外することができます
4. **クライアント側の期待**: クライアントアプリケーションがnull値と欠落フィールドをどのように解釈するかを考慮する

## 私の見解

私個人としては、**nullである要素はそもそも削除する**アプローチを好みます。このアプローチは：

- データ転送の効率性が向上する
- JSONの可読性が高まる
- 主要なスタイルガイドに準拠している

ただし、最終的には以下の要素に基づいて判断すべきです：

- プロジェクトの要件
- チームの合意
- APIの使用コンテキスト
- パフォーマンスの考慮事項

どちらのアプローチを選択する場合も、一貫性を保ち、明確に文書化することが最も重要です。

---

この記事が、JSONリクエストにおけるnull値の扱いについて考える際の参考になれば幸いです。皆さんのプロジェクトではどのようなアプローチを採用していますか？コメントで共有いただければ嬉しいです。