سؤال

We were discussing how to design a API response, for simplicity, think of having to give information of all the different types of facilities available in a city:

{
    "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. For now, we know that there are 5 facilities available generally in cities that our clients are interested in. In future, we might add more facility types to the list, though.
  2. In the example response, Gotham city has an Airport, Railway Station and a Hospital, but no Port or a Market.
  3. Each facility is very different from each other, and would have different types of fields in it. We need that flexibility.

Somebody suggested adding an extra buildings list, to indicate which buildings are present:

{
    "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
        }
    }
}

Generalising, if there are lots of fields in an object which might not be set, is it a good practice to specify them explicitly in the response from the UI? What are the pros and cons? What's the best way to do this?

هل كانت مفيدة؟

المحلول

In your case where there simply isnt a building of that type I would go for an array of Building

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

you can them simply omit entries for buildings that don't exist

نصائح أخرى

Why do you think you need to specify keys for facilities that are not present? Why not just omit them entirely.

{
    "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
            }
        }
    }
}

If the consumer of this API wants something like your buildings they can just use their equivalent of Object.keys.

Your design doesn’t allow a city to have two hospitals, Ewan’s approach allows it, so that’s a lot better. In your example, is there a port with no information, or no port? Again, in Ewan’s version you either have no “port” entry or an entry with type=port and nothing else.

The additional entry [airport, railway_station ...] has no value. At best it is useless, at worst it is inconsistent. Leave it. You know what buildings are there anyway.

As already suggested by others, it is reasonable to allow a city contain more than one facility of each type.

One more way to allow this would be to have each type of buildings represented by a property containing array of buildings of that type.

This way if you have no hospital in a city you have empty array of hospitals.

This gives you much stronger and explicit structure and types

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

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

And example data:

{
    "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": []
        }
    }
}

One side note, the nesting of facilities under city may not be necesary, but it probably depends on your requirements. Maybe it makes sense if all hospitals, airports, ports, etc have some common properties, common for every facility (and actually it seems they do - the name).

A good practice in Json communication is to never treat a missing field any differently from a field with null as the value. If you do, you will suffer in the future while trying to maintain sanity and backwards compatibility at the same time. You can ommit null in your response, to make it shorter, but don’t rely on it in your client. Take a look for example at these guideliness: https://opensource.zalando.com/restful-api-guidelines/#123

So, how would you ensure that your client displays at least a warning on a building it doesn’t recognize? As other answers suggested, use explicit field in an object to indicate its type. Most json to object mapping libraries can be configured to produce objects of appropriate subclasses.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى softwareengineering.stackexchange
scroll top