💭

REST APIのレスポンスJSONでデータが無い時の表現

2021/02/17に公開

REST APIで対象の項目にデータが無い時の表現方法が分からなかったので纏めました。

大きくは2つ、派閥があります。

  • null
  • undefined
    • データ項目を定義しない

null派閥

RFC8259でJSONが定義されています。

JSONの値としては、オブジェクト、配列、数値、文字列、またはfalse, null, trueのいずれかである、と表現されています。

なので、データが存在しない場合はnullを指定するのがあるべきであると思います。

引用


RFC8259を引用。

3.  Values

   A JSON value MUST be an object, array, number, or string, or one of
   the following three literal names:

      false
      null
      true

   The literal names MUST be lowercase.  No other literal names are
   allowed.

      value = false / null / true / object / array / number / string

      false = %x66.61.6c.73.65   ; false

      null  = %x6e.75.6c.6c      ; null

      true  = %x74.72.75.65      ; true
5.  Arrays

   An array structure is represented as square brackets surrounding zero
   or more values (or elements).  Elements are separated by commas.

   array = begin-array [ value *( value-separator value ) ] end-array

   There is no requirement that the values in an array be of the same
   type.

参照元


https://www.rfc-editor.org/rfc/rfc8259

その他(Java)


JavaのSpringが参照しているバージョンによっては、データが無い場合はnullを常に表示するようにしているようです。

バージョン:2.11は「ALLWAYS」です。
https://github.com/FasterXML/jackson-annotations/blob/2.11/src/main/java/com/fasterxml/jackson/annotation/JsonInclude.java#L68

jacksonの最新バージョン(master)は「USE_DEFAULTS」です。明示的に初期値を定義している場合は、その値を使用します。

private String id = "";

https://github.com/FasterXML/jackson-annotations/blob/master/src/main/java/com/fasterxml/jackson/annotation/JsonInclude.java#56


JavaのSpringでこの機能を変更したい場合は、次の設定ファイルを明示的に設定してください。


spring.jackson.default-property-inclusion: ALLWAYS

undefined派閥

GoogleのJSON Style Guideによると、データが無い場合は項目を排除すべきだとしています。

また、OpenAPIもデータタイプとしてはnullは定義していません。nullableとして定義できるので、nullの表現自体はできますが、データタイプとして定義していない = 項目を排除すべきだと読んでもよいかもしれません。

引用


GoogleのJSON Style Guide。

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.

Open APIのデータタイプ。

Data Types

The data type of a schema is defined by the type keyword, for example, type: string. OpenAPI defines the following basic types:
string (this includes dates and files)

- number
- integer
- boolean
- array
- object
  
These types exist in most programming languages, though they may go by different names. Using these types, you can describe any data structures.

Note that there is no null type; instead, the nullable attribute is used as a modifier of the base type.

参照元


https://google.github.io/styleguide/jsoncstyleguide.xml#Empty/Null_Property_Values

https://swagger.io/docs/specification/data-models/data-types/

その他(Java)

JavaのSpringでundefinedに変更したい場合は、次の設定ファイルを明示的に設定してください。

spring.jackson.default-property-inclusion: NON_EMPTY

結局どっちがいいの?

常にデータ構造を表現できるように、JSONのRFCに従ったnullで提供しているAPIが多そうです。

ただし、JSONそのものをデータとしてみた時には、無いデータを表現しても仕方がないのでundefinedでも良いでしょう。無駄に通信するデータを増やしても仕方ないですしね。懸念点としては、APIとして叩いた時にデータによって返却される構造が違う可能性があるので、使う側からすると難しくなってしまいます。

それを踏まえて、私はこう考えました。

  • Open APIで定義を提供しているAPI
    • undefined
  • Open APIで定義を提供していないAPI
    • null

undefinedにする場合は、レスポンスのJSONが明確に定義できることが条件だと考えています。ExcelやMarkdownとしてAPI仕様書を定義することはできますが、typo等も含めて型が必ず一致するとは限りません。

Open APIのYAMLファイルからAPIを生成していれば、型が不明確になるということもないでしょう。

今後、Open APIの後続でAPIの表現に便利なライブラリが出てきた場合、そちらで表現されていることも必須になると考えています。

終わりに

地味な内容だったので、毎回調べようとも思いましたが、RFCのリンクとかSpringでのデフォルト値等々の情報も調べたので自分用にまとめました。


この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。

Discussion