Todoservice is a project mainly written in C, based on the AGPL-3.0 license.
A not-quite-RESTful todo API implemented as C CGI with Redis backend
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.
credis - http://code.google.com/p/credis/
redis - http://code.google.com/p/redis/ Apache - presumably, but any CGI-capable web server should do
xsltproc - part of libxslt from http://www.xmlsoft.org/ curl - http://curl.haxx.se/
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.
Test Req Resp Case Method Code Type Type URI Condition/Description
GET 200 xhtml / Links (<a...>) to /todos and /version
HEAD 200 /
OPTIONS200 /
GET 200 xhtml /version API version, see below
HEAD 200 /version
OPTIONS200 /version
GET 200 xhtml /todos Returns list of links to items Includes HTML form for POSTing
HEAD 200 /todos
OPTIONS200 /todos
120 GET 500 /todos Server error, database issue
123 HEAD 500 /todos
POST 201 form xhtml /todos Returns link to new item Duplicate todo content okay
POST 201 form xhtml /todos Also empty content okay, but CONTENT_LENGTH and CONTENT_TYPE are still required
POST 400 /todos Posted todo in wrong format
POST 413 /todos Request body larger than MAX_ENTITY_LENGTH
POST 415 /todos Wrong content-type 150 POST 500 /todos Server error, database issue
GET 200 xhtml /todos/{ID}
GET 404 /todos/{ID} No such item 220 GET 500 /todos/{ID} Server error, database issue
HEAD 200 /todos/{ID}
HEAD 404 /todos/{ID} 224 HEAD 500 /todos/{ID}
OPTIONS200 /todos/{ID}
OPTIONS404 /todos/{ID} 228 OPTIONS500 /todos/{ID}
PUT 200 form /todos/{ID}
PUT 200 form /todos/{ID} Empty content okay
PUT 400 /todos/{ID} Posted todo in wrong format
PUT 404 /todos/{ID} No such item ... note, we don't allow PUTting a new resource, we'll require POSTing to the parent resource
PUT 413 /todos/{ID} Request body larger than MAX_ENTITY_LENGTH
PUT 415 /todos/{ID} Wrong content-type 260 PUT 500 /todos/{ID} Server error, database issue
DELETE 200 /todos/{ID} 290 DELETE 500 /todos/{ID} Server error, database issue
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:
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.
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.