comparison doc/rest.txt @ 5660:d8d2b7724292

First attempt at REST-API documentation Also fix operator of patch to be '@op', not 'op'. Example for retire/restore using both, DELETE and PATCH with @op=action.
author Ralf Schlatterbeck <rsc@runtux.com>
date Fri, 22 Mar 2019 11:23:02 +0100
parents
children a884698173ea
comparison
equal deleted inserted replaced
5659:1e51a709431c 5660:d8d2b7724292
1
2 ====================
3 REST API for Roundup
4 ====================
5
6 .. contents::
7 :local:
8
9 Introduction
10 ------------
11
12 After the last 1.6.0 Release, a REST-API developed in 2015 during a Google
13 Summer of Code (GSOC) by Chau Nguyen, supervised by Ezio Melotti was
14 integrated. The code was then updated by John Rouillard and Ralf
15 Schlatterbeck to fix some shortcomings and provide the necessary
16 functions for a single page web application, e.g. etag support among
17 others.
18
19 Enabling the REST API
20 ---------------------
21
22 The REST API can be disabled in the ``[web]`` section of ``config.ini``
23 via the variable ``enable_rest`` which is ``yes`` by default.
24
25 The REST api is reached via the ``/rest/`` endpoint of the tracker URL.
26
27
28 Client API
29 ----------
30
31 The top-level REST url ``/rest/`` will display the current version of
32 the REST API (Version 1 as of this writing) and some links to relevant
33 endpoints of the API. In the following the ``/rest`` prefix is ommitted
34 from relative REST-API links for brevety.
35
36 Summary
37 =======
38
39 A Summary page can be reached via ``/data/summary`` via the ``GET`` method.
40 This is currently hard-coded for the standard tracker schema shipped
41 with roundup and will display a summary of open issues.
42
43 Data
44 ====
45
46 All the links mentioned in the following support the http method ``GET``.
47 Results of a ``GET`` request will always return the results as a
48 dictionary with the entry ``data`` referring to the returned data.
49
50 The ``/data`` link will display a set of classes of the tracker. All
51 classes can be reached via ``/data/<classname>`` where ``<classname>``
52 is replace with the name of the class to query, e.g. ``/data/issue``.
53 Individual items of a class (e.g. a single issue) can be queried by
54 giving the issue-id, e.g., ``/data/issue/42``. Individual properties of
55 an item can be queried by appending the property, e.g.,
56 ``/data/issue/42/title``.
57
58 When performing the ``GET`` method on a class (e.g. ``/data/issue``), the
59 number of items is returned in ``@total_size``. Then a ``collection``
60 list follows which contains the id and link to the respective item.
61
62 When performing the ``GET`` method on an item (e.g. ``/data/issue/42``), a
63 ``link`` attribute contains the link to the item, ``id`` contains the
64 id, type contains the class name (e.g. ``issue`` in the example) and an
65 ``etag`` property can be used to detect modifications since the last
66 query. The individual properties of the item are returned in an
67 ``attributes`` dictionary. The properties returned depend on the
68 permissions of the account used for the query.
69
70 A ``GET`` method on a property (e.g. ``/data/issue/42/title``) returns the
71 link, an ``@etag``, the type of the property (e.g. "<type str>") the id
72 of the item and the content of the property in ``data``.
73
74 Only class links support the ``POST`` method for creation of new items
75 of a class, e.g., a new issue via the ``/data/issue`` link. The post
76 gets a dictionary of keys/values for the new item. It returns the same
77 parameters as the GET method after successful creation.
78
79 All endpoints support an ``OPTIONS`` method for determining which
80 methods are allowed on a given endpoint.
81
82 The method ``PUT`` is allowed on individual items, e.g.
83 ``/data/issue/42`` as well as properties, e.g.,
84 ``/data/issue/42/title``. On success it returns the same parameters as
85 the respective ``GET`` method. Note that for ``PUT`` an Etag has to be
86 supplied, either in the request header or as an @etag parameter.
87
88 The method ``DELETE`` is allowed on items, e.g., ``/data/issue/42`` and
89 will retire (mark as deleted) the respective item. On success it will
90 only return a status code. It is also possible to call ``DELETE`` on a
91 property of an item, e.g., ``/data/issue/42/nosy`` to delete the nosy
92 list. The same effect can be achieved with a ``PUT`` request and an
93 empty new value.
94
95 Finally the ``PATCH`` method can be applied to individual items, e.g.,
96 ``/data/issue/42`` and to properties, e.g., ``/data/issue/42/title``.
97 This method gets an operator ``@op=<method>`` where ``<method`` is one
98 of ``add``, ``replace``, ``remove``, only for an item (not for a
99 property) an additional operator ``action`` is supported. If no operator
100 is specified, the default is ``replace``. The first three operators are
101 self explanatory. For an ``action`` operator an ``@action_name`` and
102 optional ``@action_argsXXX`` parameters have to be supplied. Currently
103 there are only two actions without parameters, namely ``retire`` and
104 ``restore``. The ``retire`` action on an item is the same as a
105 ``DELETE`` method, it retires the item. The ``restore`` action is the
106 inverse of ``retire``, the item is again visible.
107 On success the returned value is the same as the respective ``GET``
108 method.
109
110 sample python client
111 ====================
112
113 The client uses the python ``requests`` library for easier interaction
114 with a REST API supporting JSON encoding::
115
116
117 >>> import requests
118 >>> u = 'http://user:password@tracker.example.com/demo/rest/data/'
119 >>> s = requests.session()
120 >>> r = s.get(u + 'issue/42/title')
121 >>> if r.status_code != 200:
122 ... print("Failed: %s: %s" % (r.status_code, r.reason))
123 ... exit(1)
124 >>> print (r.json() ['data']['data']
125 TEST Title
126 >>> r = s.post (u + 'issue', data = dict (title = 'TEST Issue'))
127 >>> if not 200 <= r.status_code <= 201:
128 ... print("Failed: %s: %s" % (r.status_code, r.reason))
129 ... exit(1)
130 >>> print(r.json())
131
132 Retire/Restore::
133 >>> r = s.delete (u + 'issue/42')
134 >>> print (r.json())
135 >>> r = s.get (u + 'issue/42')
136 >>> etag = r.headers['ETag']
137 >>> print("ETag: %s" % etag)
138 >>> etag = r.json()['data']['@etag']
139 >>> print("@etag: %s" % etag)
140 >>> h = dict(ETag = etag)
141 >>> d = {'@op:'action', '@action_name':'retire'}
142 >>> r = s.patch(u + 'issue/42', data = d, headers = h)
143 >>> print(r.json())
144 >>> d = {'@op:'action', '@action_name':'restore'}
145 >>> r = s.patch(u + 'issue/42', data = d, headers = h)
146 >>> print(r.json())
147

Roundup Issue Tracker: http://roundup-tracker.org/