-
Notifications
You must be signed in to change notification settings - Fork 0
A not-quite-RESTful todo API implemented as C CGI with Redis backend
License
erikmack/todoservice
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
todoservice
===========
A toy implementation of a not-quite-RESTful "todo" service implemented
as a CGI program with Redis as a data store.
Why? I wanted a simple service like this that could be used over a network, and
get all the things that come for nearly-free with HTTP (authentication, encryption,
proxy support, etc.)
Also, freedom and data ownership! The Affero licensing means you are free to
change the source as you like (with a share-alike condition). And when you run
your own data servers instead of using hosted solutions, you regain privacy and
the power that is lost when we let others take care of our data.
This is a very simple API for a to-do list. A "todo" is simply an ASCII
string (with no supporting metadata like completion info, etc.) The API
allows for GET/PUT/POST/DELETE for todos.
Some sample apache configurations are included in example/apache_vhosts.
A serviceable shell client lives in example/client.
Although the service isn't quite RESTful, it could be made so without too much
work.
A true RESTful implementation would take the hypermedia constraint a little more
seriously. While this API exposes all GETtable resources as links, it should
also have a POST form at the /todos URL, and PUT/DELETE forms at the /todo/{ID}
URLs. This would make the service self-describing, and clients could discover
the possible interactions, rather than having them hard-coded and
tightly-coupled.
Redis is used as the data store. By default, the CGI script will expect Redis
to be listening at localhost:6379, and use database 0, but this can be adjusted
if necessary. Run ./configure --help to see how to override the defaults.
A decent battery of unit tests is included, mostly just to guard what URIs
return what error codes with which methods and under which conditions. "make
check" will run them.
Although only ASCII-encodable todos are supported at this point, multibyte todos
could be implemented without too much work. Redis doesn't care about encoding,
so it would mostly be a matter of setting the response headers correctly.
Dependencies
============
Build-time
----------
credis - http://code.google.com/p/credis/
Run-time
--------
redis - http://code.google.com/p/redis/
Apache - presumably, but any CGI-capable web server should do
td client
---------
xsltproc - part of libxslt from http://www.xmlsoft.org/
curl - http://curl.haxx.se/
Installation
============
the usual:
./configure
make
sudo make install
... will do, although a preliminary
./configure --help
... is always instructive
The CGI binary "todoservice" is installed into /usr/libexec. See the example apache
vhost configurations.
The test client "td" is installed into /usr/bin. Try "td --help" for a little
guidance.
URI Specification
=================
Test Req Resp
Case Method Code Type Type URI Condition/Description
---- ------ ---- ---- ---- --- ---------------------
010. GET 200 xhtml / Links (<a...>) to /todos and /version
013. HEAD 200 /
016. OPTIONS200 /
020. * 405 /
050. GET 200 xhtml /version API version, see below
053. HEAD 200 /version
056. OPTIONS200 /version
060. * 405 /version
110. GET 200 xhtml /todos Returns list of links to items
Includes HTML form for POSTing
113. HEAD 200 /todos
116. OPTIONS200 /todos
120 GET 500 /todos Server error, database issue
123 HEAD 500 /todos
130. POST 201 form xhtml /todos Returns link to new item
Duplicate todo content okay
135. POST 201 form xhtml /todos Also empty content okay, but
CONTENT_LENGTH and CONTENT_TYPE
are still required
140. POST 400 /todos Posted todo in wrong format
143. POST 413 /todos Request body larger than MAX_ENTITY_LENGTH
145. POST 415 /todos Wrong content-type
150 POST 500 /todos Server error, database issue
160. * 405 /todos
200. GET 200 xhtml /todos/{ID}
210. GET 404 /todos/{ID} No such item
220 GET 500 /todos/{ID} Server error, database issue
222. HEAD 200 /todos/{ID}
223. HEAD 404 /todos/{ID}
224 HEAD 500 /todos/{ID}
226. OPTIONS200 /todos/{ID}
227. OPTIONS404 /todos/{ID}
228 OPTIONS500 /todos/{ID}
230. PUT 200 form /todos/{ID}
235. PUT 200 form /todos/{ID} Empty content okay
240. PUT 400 /todos/{ID} Posted todo in wrong format
250. PUT 404 /todos/{ID} No such item ... note, we don't allow
PUTting a new resource, we'll require POSTing
to the parent resource
253. PUT 413 /todos/{ID} Request body larger than MAX_ENTITY_LENGTH
255. PUT 415 /todos/{ID} Wrong content-type
260 PUT 500 /todos/{ID} Server error, database issue
270. DELETE 200 /todos/{ID}
290 DELETE 500 /todos/{ID} Server error, database issue
295. * 405 /todos/{ID}
300. * 404 /todos/*/...
900. 404 *
Notes:
- {ID} is a human-readable, slugified string of the first token
of the todo text, or the first N tokens that will make the URI
unique. If a subsequent PUT changes the first tokens of the todo
text, the URI will not change. The URI will have an appended index
(e.g. /todos/pay-bills-2) in the case of duplicates or any other case
where uniqueness can't be guaranteed by the text of the todo alone.
- /version returns the API version, which is not the product
version. We copy the versioning scheme used by libtool:
major,minor,age
where:
- major bump means the API changed
- minor bump means the internals changed (no API changes)
- age bump measures backward-compatibility
(can only occur with a major bump)
- Content types:
xhtml = application/xhtml+xml
form = application/x-www-form-urlencoded
- The . after the test case (ex. "900." ) means a unit test exists for
this case.
Redis Schema
============
ids - set of IDs (described above)
id:foo:text - the text of the todo with ID 'foo'. Does not include a
null-terminator character.
Future releases will contain other attributes like date, tags, state, etc.
About
A not-quite-RESTful todo API implemented as C CGI with Redis backend
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published