swapi
swapi copied to clipboard
Meta property on resources
I propose taking the properties of a resource that are actually properties of the system that stores the resource and moving them into a property called "meta".
i.e. If some resource is:
{
"name": "Luke Skywalker",
"height": "1.72 m",
"mass": "77 Kg",
"hair_color": "Blond",
"skin_color": "Caucasian",
"eye_color": "Blue",
"birth_year": "19 BBY",
"gender": "Male",
"homeworld": "http://swapi.co/api/planets/1/",
"films": [
"http://swapi.co/api/films/1/",
"http://swapi.co/api/films/2/",
"http://swapi.co/api/films/3/"
],
"species": [
"http://swapi.co/api/species/1/"
],
"vehicles": [
"http://swapi.co/api/vehicles/14/",
"http://swapi.co/api/vehicles/30/"
],
"starships": [
"http://swapi.co/api/starships/12/",
"http://swapi.co/api/starships/22/"
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-10T13:52:43.172000Z",
"url": "http://swapi.co/api/people/1/"
}
Then the resource would be:
{
"name": "Luke Skywalker",
"height": "1.72 m",
"mass": "77 Kg",
"hair_color": "Blond",
"skin_color": "Caucasian",
"eye_color": "Blue",
"birth_year": "19 BBY",
"gender": "Male",
"homeworld": "http://swapi.co/api/planets/1/",
"films": [
"http://swapi.co/api/films/1/",
"http://swapi.co/api/films/2/",
"http://swapi.co/api/films/3/"
],
"species": [
"http://swapi.co/api/species/1/"
],
"vehicles": [
"http://swapi.co/api/vehicles/14/",
"http://swapi.co/api/vehicles/30/"
],
"starships": [
"http://swapi.co/api/starships/12/",
"http://swapi.co/api/starships/22/"
],
"meta": {
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-10T13:52:43.172000Z",
"url": "http://swapi.co/api/people/1/"
}
}
The change being that the last three properties don't actually describe the resource but in fact describe the storage system. "created" is not Luke's birth year, and "edited" makes little sense.
I've taken to using a schema like this for APIs I've implemented as it is a great place to put other extended information that describes the system being used to store the resource. i.e. creation and edited dates, who created and edited, permissions that you (the callee) have on this resource, metrics about the system and not the resource itself (i.e. how many times has this resource been requested, rather than how tall is this person), and so on.
This change is really to help the API grow in functionality in the future and to help the schema communicate more clearly which parts of the resource schema describe the resource.
Maybe for created and edited, but the url attribute it vital for HATEOAS and I personally think it should be a direct attribute on the resource and not nested.
I'd agree with the view that the "self" URL is special.
I've done both things... adding it as the first property on a resource, and also adding it as a "self" URL on a list of links about the resource (taking the view that philosophically the URL doesn't really describe the resource but is a property of the system storing the resource)
Example of a "meta" object on a large and complex API:
"meta":{
"created": "2013-04-11T05:52:46.362755Z",
"createdBy": {
...
},
"flags": {
"sticky": false,
"open": true,
"deleted": false,
"moderated": false,
"unread": true
},
"links":[
{"rel":"self", "href":"/api/foos/1"},
],
"permissions":{
"create":false,
"read":true,
"update":false,
"delete":false
}
}
I think Meta is okay for the created and updated values. Accepted this into version 2 (whenever I find spare time to roll that out)
We don't need anything like permissions as we can just call the HTTP HEAD method on the resource and determine the CRUD actions based on the allowed HTTP methods. Also, swapi only supports GET anyway.