Skip to content

erikmack/todoservice

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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

No packages published

Languages