[openstack-dev] [ara] Best practices on what to return from REST API ?
David Moreau Simard
dms at redhat.com
Wed Aug 9 04:07:34 UTC 2017
So I'm making what I think is good progress towards the python and
REST API implementation for ARA but now I have a question.
I've made the following API "GET" endpoints:
- files (saved Ansible files)
- hosts (hosts involved in playbooks and their facts, if available)
- playbooks (data about the actual playbook and ansible parameters)
- plays (data about plays)
- results (actual results like 'ok', 'changed' as well as the data
from the Ansible module output)
- tasks (data about the task, like name, action and file path)
Each endpoint is self-sufficient and allows consumers to search
individual endpoints as required, for example:
(See attached links for actual and real output)
- GET /api/v1/plays #  List all plays
- GET /api/v1/plays?id=1 #  Get play with id 1
- GET /api/v1/plays?playbook_id=1 #  List all plays for playbook_id 1
The mechanism and logic is the same for all endpoints.
Where I get a bit doubtful is because some components have
relationships, like the following:
- files have file contents (file.content) 
- hosts have facts (host.facts) 
- tasks have results (task.results) 
- playbooks basically aggregate everything (playbook.files,
playbook.hosts, playbook.plays, playbook.results, playbook.tasks) so
it's potentially huge.
So, what is the best practice here ?
I'm thinking that returning all the available data on a LIST call (GET
/api/v1/playbooks) is nuts because of the potential amount of data
I'm torn between two different approaches but I would be happy to be
convinced there's a better way.
1) Only return "child" resources on specific call
So, when doing a GET on something that is expected to return a list
(GET /api/v1/playbooks), do not return child resources.
And, when doing a GET on the specific resource (GET
/api/v1/playbooks?id=1), display all the child resources.
This would be sort of analogous to how python-openstackclient has
different fields when doing "openstack server list" and "openstack
However, the amount of data for even a single playbook is likely very
significant at scale.
2) Require sub calls for different components
In this method, we would not return child resources when doing a list
call (GET /api/v1/playbooks) or when doing a specific call (GET
To get child resources, you would need to pick them up one by one, ex:
for playbook in playbooks:
files = FileApi.get(playbook_id=playbook['id']
hosts = HostApi.get(playbook_id=playbook['id']
plays = PlayApi.get(playbook_id=playbook['id']
I feel like approach #2 would be best -- for running at scale but also
in the context of loading data asynchronously and concurrently.
Any opinions ?
David Moreau Simard
Senior Software Engineer | OpenStack RDO
dmsimard = [irc, github, twitter]
More information about the OpenStack-dev