web-dev-qa-db-ja.com

null許容フィールドを使用してAPI JSON応答を設計する方法

簡単にするために、APIレスポンスを設計する方法について説明しましたが、都市で利用できるさまざまなタイプの施設すべての情報を提供する必要があると考えます。

{
    "city": {
        "cityName": "Gotham",
        "population": "8620000",
        "facilities": {
            "airport": {
                "name": "Batman International Airport",
                "numRunways": 7,
                "dailyCommuters": 340000
            },
            "railwayStation": {
                "name": "Gotham Downtown Rail Station",
                "platforms": 12,
                "dailyCommuters": 40000
            },
            "hospital": {
                "name": "Joker Memorial Nursing Home",
                "beds": 300
            },
            "port": null,
            "market": null
        }
    }
}
  1. 現在のところ、クライアントが関心を持っている都市では、一般的に5つの施設が利用可能であることがわかっています。将来的には、施設タイプをリストに追加する可能性があります。
  2. 応答例では、ゴッサム市には空港、駅、病院がありますが、港や市場はありません。
  3. 各施設は非常に異なっており、その中にさまざまなタイプのフィールドがあります。その柔軟性が必要です。

誰かが追加のbuildingsリストを追加して、どの建物が存在するかを示すことを提案しました:

{
    "city": {
        "cityName": "Gotham",
        "population": "8620000",
        "buildings": {
            "buildings": ["AIRPORT", "RAILWAY_STATION", "HOSPITAL"],

            "airport": {
                "name": "Batman International Airport",
                "numRunways": 7,
                "dailyCommuters": 340000
            },
            "railwayStation": {
                "name": "Gotham Downtown Rail Station",
                "platforms": 12,
                "dailyCommuters": 40000
            },
            "hospital": {
                "name": "Joker Memorial Nursing Home",
                "beds": 300
            },
            "port": null,
            "market": null
        }
    }
}

一般化すると、オブジェクトに設定されていない可能性のあるフィールドがたくさんある場合、UIからの応答でそれらを明示的に指定することは良い習慣ですか?長所と短所は何ですか?これを行う最良の方法は何ですか?

4
daltonfury42

そのタイプの建物が単にないあなたの場合、私は建物の配列に行きます

{
    "city" : {
        "buildings" : [
            {
                "type": "airport",
                "name": "Batman International Airport",
                "numRunways": 7,
                "dailyCommuters": 340000
            },
            {
                "type": "hospital",
                "name": "Joker Memorial Nursing Home",
                "beds": 300
            }
         ]
     }
}

存在しない建物のエントリは省略できます

5
Ewan

存在しないfacilitiesのキーを指定する必要があるのはなぜですか?それらを完全に省略しないのはなぜですか。

{
    "city": {
        "cityName": "Gotham",
        "population": "8620000",
        "facilities": {
            "airport": {
                "name": "Batman International Airport",
                "numRunways": 7,
                "dailyCommuters": 340000
            },
            "railwayStation": {
                "name": "Gotham Downtown Rail Station",
                "platforms": 12,
                "dailyCommuters": 40000
            },
            "hospital": {
                "name": "Joker Memorial Nursing Home",
                "beds": 300
            }
        }
    }
}

このAPIのコンシューマーがbuildingsのようなものを必要とする場合、Object.keysに相当するものを使用できます。

2
Caleth

あなたの設計では、都市に2つの病院を設けることはできませんが、ユアンのアプローチではそれが可能になるため、はるかに優れています。あなたの例では、情報のないポート、またはポートがないのですか?繰り返しますが、Ewanのバージョンでは、「ポート」エントリがないか、type = portのみのエントリがあります。

追加のエントリ[airport、railway_station ...]には値がありません。せいぜい役に立たず、最悪の場合、一貫性がありません。そのままにしておきます。とにかく、どんな建物があるのか​​知っています。

2
gnasher729

他の人がすでに示唆しているように、都市に各タイプの複数の施設を含めることを許可するのは合理的です。

これを可能にするもう1つの方法は、各タイプの建物を、そのタイプの建物の配列を含むプロパティで表すことです。

この方法では、都市に病院がない場合、空の病院が並んでいます。

これにより、より強力で明示的な構造とタイプが得られます

public interface IFacilities
{
  airports: IAirport[]
  railwayStations: IRailwayStation[]
  hospitals: IHospital[]
  ports: IPort[]
  markets: IMarket[]
}

public interface ICity
{
  cityName: string
  population: number
  facilities: IFacilities
}

そしてサンプルデータ:

{
    "city": {
        "cityName": "Gotham",
        "population": "8620000",
        "facilities": {
            "airports": [{
                "name": "Batman International Airport",
                "numRunways": 7,
                "dailyCommuters": 340000
            }],
            "railwayStations": [{
                "name": "Gotham Downtown Rail Station",
                "platforms": 12,
                "dailyCommuters": 40000
            }],
            "hospitals": [{
                "name": "Joker Memorial Nursing Home",
                "beds": 300
            }],
            "ports": [],
            "markets": []
        }
    }
}

余談ですが、市の下での施設のネストは必ずしも必要ではありませんが、おそらく要件によって異なります。たぶん、すべての病院、空港、港などに、すべての施設に共通するいくつかの共通のプロパティがある場合に理にかなっています(そして実際には、名前がそうです)。

0
slepic

Json通信の良い習慣は、欠落しているフィールドを、値としてnullを持つフィールドと異なる方法で処理しないことです。これを行うと、将来、健全性と下位互換性を同時に維持しようとしながら苦しむことになります。レスポンスのnullを省略して短くすることはできますが、クライアントではそれに依存しないでください。これらのガイドラインの例を見てみましょう: https://opensource.zalando.com/restful-api-guidelines/#12

では、クライアントが認識できない建物について少なくとも警告を表示するようにするにはどうすればよいでしょうか。他の回答が示唆するように、オブジェクトの明示的なフィールドを使用して、そのタイプを示します。ほとんどのjsonからオブジェクトへのマッピングライブラリは、適切なサブクラスのオブジェクトを生成するように構成できます。

0
Mateusz Stefek