2

I find that in the early stages of a project the structure of the data returned by the server can change quite frequently as the data model changes.

For example, if I'm building an application that plots the locations of local points of interest I might start by returning json that looks like this :

[{"name" : "Odeon", "poiType" : "cinema", "lat" : 34.4, "lon" : 10.3}, 
 {"name" : "McDonalds", "poiType" : "restaurant", "lat" : 34.5", "lon" : "10.5"}, ...]

On the client I might have several components that need the lat/lon information, and they would typically access the data as follows:

function showPointsOfInterest(pois) {
    pois.forEach(function (poi) {
         var icon = getIcon(poi.poiType); 
         addToMap(poi.lon, poi.lat, icon);
     })
}

function listPointsOfInterest(pois) {
     pois.forEach(function (poi) { 
         var icon = getIcon(poi.poiType); 
         addToList(poi.lon, poi.lat, icon);
     })
}

I then decide that I would like to change the data structure so that it now looks like

[
{
    "name": "Odeon",
    "type": "cinema",
    "location": {
        "coordinates": {
            "lat": 34.4,
            "lon": 10.3
        },
        "address": "Main St, 54"
    }
},
{
    "name": "McDonalds",
    "type": "restaurant",
    "location": {
        "coordinates": {
            "lat": 34.5,
            "lon": 10.5
        },
        "address": "Main St, 154"
    }
}, ... ]

The changes being that poiType is now type, and lat and lon are now children of location.coordinates.

I now need to change my client side code to

function showPointsOfInterest(pois) {
    pois.forEach(function (poi) {
     var icon = getIcon(poi.type);
      var coords = poi.location.coordinates; 
      addToMap(coords.lon, coords.lat, icon);
   })
}

function listPointsOfInterest(pois) {
    pois.forEach(function (poi) { 
        var icon = getIcon(poi.type);
        var coords = poi.location.coordinates;  
        addToList(coords.lon, coords.lat, icon);
    })
}

Having to go through the code and find where I'm accesssing poiType , lat and lon can be a pain.

So I'm wondering if it's good practice to create some utility functions like

function getLon(poi) {
    return poi.location.coordinates.lon;
}

function getLat(poi) {
    return poi.location.coordinates.lat;
}

function getType(poi) {
    return poi.type;
}

and then having

function showPointsOfInterest(pois) {
    pois.forEach(function (poi) {
     var icon = getIcon(getType(poi)); 
     addToMap(getLon(poi), getLat(poi), icon);
   })
}

function listPointsOfInterest(pois) {
    pois.forEach(function (poi) { 
        var icon = getIcon(getType(poi)); 
        addToList(getLon(poi), getLat(poi), icon);
    })
}

The advantage of this approach is that if my data model changes I only need to make changes in my utility functions.

Is this the best approach? Are there any downsides to doing this?

1 Answer 1

2

The usual way is to version the API. Your API still responds with the old data structure at the old URI. Then you add another URI to your API with the new data structure. Then the client code still continues to function on the old data until you get around to changing it over. This is how you have to do it when you have external customers depending on your API.

If you're just being a perfectionist, and then keeping the client code in sync with the changes, then you can use whatever strategy works for you. Bear in mind that the data you return from the API doesn't have to be the canonical version of the data. It could be a representation of the data that best suits the use case. In this instance, a flat object seems just as good if not better than the more organized version.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.