I am handcrafting a JSON Schema for the API and there is some meta missing from the nested 'returns' objects and arrays.
The relevant information I need is:
- if it is an array, can it be undefined (missing) or will it simply be empty
- if it is an object, can it be undefined (missing)
Types in question:
- site.styling - ?
- site.aliases - can be undefined
- associated_user_stub.on_site - ?
- user.badge_counts - ?
- statistics.api_version - ?
- question.migrated - ?
- question.owner - ?
- question.tags - ?
- answer.owner - ?
- comment.owner - ?
- comment.reply_to_user - ?
- badge.user - ?
- post_timeline.user - ?
- post_timeline.owner - ?
- revision.user - ?
- revision.tags - ?
- revision.last_tags - ?
Thanks.
Implementation Note:
The reason I am handcrafting this instead of parsing and generating as I am wont to do is directly related to the reason for this post i.e. the auto format used to produce the 'returns' structure documentation does not produce any meta data on these elements.
The 'returns' structures, for the most part, are clear and easy to understand, but the lack of this meta leaves a lot to be guessed. Computers and programmers who try to tell them what to do do not really like to guess at the structure of core data structures. ;-)
It is my hope that after I publish JSON Schema for the API, the benefits of such a format may become apparent to those designing the next API.
I don't think I would suggest replacing the help page structures, which are easy to read and fine for casual perusal with the more verbose and normative JSON Schema.
Rather the machine readable JSON Schema could be served with a /?schema
parameter much the same way as a WSDL.
As reference, follows a JSON Schema fragment that describes a question. Notice the lack of ambiguity, especially for .tags and .owner
"question": {
"description": "",
"type": "object",
"properties": {
"tags": {
"description": "",
"optional": true,
"type": "array",
"items": {
"type": "string"
}
},
"answer_count": {
"description": "number of answer on this question",
"type": "integer",
"optional": false
},
"accepted_answer_id": {
"description": "id of the accepted answer",
"type": "integer",
"optional": true
},
"favorite_count": {
"description": "number of users who have favorited this question",
"type": "integer",
"optional": false
},
"bounty_closes_date": {
"description": "date the bounty closes on this question",
"type": "integer",
"format": "utc-seconds",
"optional": true
},
"bounty_amount": {
"description": "amount of rep the bounty is worth",
"type": "integer",
"optional": true
},
"closed_date": {
"description": "date this question was closed",
"type": "integer",
"format": "utc-seconds",
"optional": true
},
"closed_reason": {
"description": "why this question was closed",
"type": "string",
"maxLength": 500,
"optional": true
},
"protected_date": {
"description": "date this question was protected",
"type": "integer",
"format": "utc-seconds",
"optional": true
},
"question_timeline_url": {
"description": "link to the timeline of this question",
"type": "string",
"format": "uri",
"optional": false
},
"question_comments_url": {
"description": "link to the comments on this question",
"type": "string",
"format": "uri",
"optional": false
},
"question_answers_url": {
"description": "link to the answers on this question",
"type": "string",
"format": "uri",
"optional": false
},
"question_id": {
"description": "id of the question this post is or is on",
"type": "integer",
"optional": false
},
"locked_date": {
"description": "date this question was locked",
"type": "integer",
"format": "utc-seconds",
"optional": true
},
"creation_date": {
"description": "date this post was created",
"type": "integer",
"format": "utc-seconds",
"optional": false
},
"last_edit_date": {
"description": "last time this post was edited",
"type": "integer",
"format": "utc-seconds",
"optional": true
},
"last_activity_date": {
"description": "last time this post had any activity",
"type": "integer",
"format": "utc-seconds",
"optional": true
},
"up_vote_count": {
"description": "number of up votes on this post",
"type": "integer",
"optional": false
},
"down_vote_count": {
"description": "number of down votes on this post",
"type": "integer",
"optional": false
},
"view_count": {
"description": "number of times this post has been viewed",
"type": "integer",
"optional": false
},
"score": {
"description": "score of this post",
"type": "integer",
"optional": false
},
"community_owned": {
"description": "whether this post is community owned",
"type": "boolean",
"optional": false
},
"title": {
"description": "title of this post, in plaintext",
"type": "string",
"optional": false,
"maxLength": 200
},
"body": {
"description": "body of this post, rendered as HTML",
"type": "string",
"maxLength": 40000,
"optional": true
},
"owner": {
"description": "",
"optional": true,
"type": "#.properties.user_stub"
},
"migrated": {
"description": "",
"optional": true,
"extends": {
"$ref": "#.properties.migration"
}
},
"answers": {
"description": "",
"optional": true,
"type": "array",
"items": {
"$ref": "#.properties.answer"
}
},
"comments": {
"description": "",
"optional": true,
"type": "array",
"items": {
"$ref": "#.properties.comment"
}
}
}
}