Skip to content

Commit

Permalink
update docs and such
Browse files Browse the repository at this point in the history
  • Loading branch information
Stevan Little committed Jan 22, 2011
1 parent f6badb5 commit eabe1c5
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 232 deletions.
2 changes: 1 addition & 1 deletion ChangeLog
@@ -1,4 +1,4 @@
Revision history for Perl extension Jackalope
Revision history for Perl extension Jackalope-JS

0.01
- ...
29 changes: 3 additions & 26 deletions Makefile.PL
Expand Up @@ -2,38 +2,15 @@ use strict;
use warnings;
use inc::Module::Install;

name 'Jackalope';
all_from 'lib/Jackalope.pm';
name 'Jackalope-JS';
all_from 'lib/Jackalope/JS.pm';
license 'perl';

requires 'Moose' => 0;
requires 'MooseX::Getopt' => 0;
requires 'MooseX::Types::Path::Class' => 0;
requires 'MooseX::Params::Validate' => 0;
requires 'Bread::Board' => 0;
requires 'Throwable::Error' => 0;
requires 'Plack' => 0;
requires 'CGI::Expand' => 0;
requires 'JSON::XS' => 0;
requires 'Try::Tiny' => 0;
requires 'Class::Load' => 0;
requires 'Clone' => 0;
requires 'Digest' => 0;
requires 'File::Spec::Unix' => 0;
requires 'List::AllUtils' => 0;
requires 'Data::Visitor::Callback' => 0;
requires 'Scalar::Util' => 0;
requires 'Data::Peek' => 0;
requires 'Data::Dumper' => 0;
requires 'Devel::PartialDump' => 0;
requires 'Template' => 0;
requires 'FindBin' => 0;
requires 'Jackalope' => 0;

build_requires 'Test::More' => 0;
build_requires 'Test::Moose' => 0;
build_requires 'Test::Fatal' => 0;
build_requires 'Test::Builder' => 0;
build_requires 'HTTP::Request::Common' => 0;

tests('t/*.t');

Expand Down
212 changes: 7 additions & 205 deletions README.md
@@ -1,178 +1,7 @@
# Jackalope

Jackalope is a framework for building REST style web services with embedded
hypermedia controls. It was heavily inspired by the description of "Level 3"
web services as described in [this article](http://martinfowler.com/articles/richardsonMaturityModel.html#level3)
by Martin Fowler and the book [REST in Practice](http://restinpractice.com/default.aspx).

## Core Concepts

Jackalope is built of a couple of different parts. The first part is the
schema language, which describes the messages to be sent and recieved. The
second part is the hypermedia controls, which are themselves described
in the schema language. And the last part is the REST style web services.

### Schema Language

The schema language is actually just Perl data structures, but it is simple enough
that it could be written in most any simple data serialization language, like JSON,
YAML or a dialect of XML. The schema language is also self-describing, meaning that
each core element of the language is described with the language itself. There is
support for a set of core types which are shown below in the type heirarchy.

Any
Null
Boolean
Number
Integer
String
Array[ T ]
Object[ String, T ]
Schema

Additionally the core schema language also supports references (using the JSPON
$ref syntax) and through the use of references it is also possible to 'extend'
a schema, which is similar to object oriented inheritance, but different.

It should be noted that the schema language draws much of it's syntactic inspiration
from [JSON-Schema](http://www.json-schema.org) however the underlying implementation
and core philosophy differ greatly.

The documentation for the schema types themselves is contained within the
schema (see, like really self-decribing), take a look at Jackalope::Schema::Spec
to see this documentation. I recommend reading that document from top to bottom,
after which you should have all the information to understand what you just read,
so I recommend re-reading it then. Hopefully at that point, it will all make sense.

### Hypermedia controls

In the core set of schemas we also provide a basic 'linkrel' schema and an 'hyperlink'
schema. The 'linkrel' schema is for describing the concept of a link enough so that
a link could easily be created from the available metadata. The 'hyperlink' schema is
for describing the concrete implementation of a 'linkrel'. It is perhaps useful to
think of a 'linkrel' like a class and 'hyperlink' like an object instance, they have
a similar relationship to one another.

The base 'any' schema type provides an optional 'links' property, which is a key-value
mapping of 'linkrels' where the 'rel' name is the key. These are meant to describe the
possible actions that can be taken against a given schema. Think of them as methods,
where the schema is the class. These are also used by the REST style web services to
generate the routes that can be called on the service, and used to generate a set of
hypermedia controls for an instance of the schema.

### REST style web services

This part of Jackalope starts to get more opinionated. Currently it provides a
basic set of tools for exposing discoverable services and another set of tools
to manage a collection a resources in a CRUD like manner. It borrows some of the
basic HTTP interactions from the ATOM publishing protocol and Microsoft's Cannonical
REST Entity model, then mixed up with some of my personal opinions.

It should be noted that there is more to REST then simple CRUD actions on
resource collections. Jackalope provides all the building blocks for constructing
a REST application using any kind of custom workflow you would like. However,
because CRUD is so common, currently it is available "out of the box" with
Jackalope.

We extend the base Jackalope spec for this part, adding to it a 'web/resource' and
'web/resource/ref' schemas to help you manage your resources. And the
'jackalope/rest/service/read-only', 'jackalope/rest/service/non-editable' and
'jackalope/rest/service/crud' schemas, which can be extended to add a reasonable
set of default 'linkrels' for a schema. These can all be seen in the
Jackalope::REST::Schema::Spec module.

These are the two core components of the REST part of Jackalope, Resources and
Services, which will discuss more below.

#### Resources

Within resources there are two key concepts; resources and resource repositories.
A resource is the transport format, it looks something like this:

{
id : <string id>,
body : <data structure modeled by your schema>,
version : <digest of the body>,
links : [ <array of hyperlink items> ]
}

The 'id' field is the lookup key for this given resource in the repository and the
'body' is what you have stored in the resource repository. The 'version' is a digest
of the body constructed by creating an SHA-256 hash of the cannonical JSON of the body.
And then finally the optional 'links' is an array of 'hyperlink' items which represent
the other available services for this resource (ex: read, update, delete, etc.)

We also have a concept of resource references, which is a representation of a
reference to a resource. It looks something like this:

{
$id : <string id>,
type_of : <schema uri of resource this refers to>,
version : <digest of the body of the resource this refers to>,
link : <hyperlink to read this resource>
}

The '$id' field is the same as the 'id' field in a resource, the 'type_of' field
is the schema this '$id' refers too. Then optionally we have a 'version', which is
as described above and could be used in your code to check that the resource being
referred to has not changed. We also optionally have a 'link', which is an 'hyperlink'
of the 'read' service for this resource (basically a link to the resource itself).

The next concept is the resource repository. Currently we supply a basic role that will
wrap around your data repository and you only need worry about the 'body' of the resource
and it will handle wrapping that into a proper resource as well as the generation and
checking the version string. This currently plugs in directly to the built-in CRUD
service, but can also be useful outside of that as well.

#### Services

Currently the services in Jackalope are really only building blocks, it is up to you
to assemble them in the way you need. The goal is to provide enough of a framework
so that mechanics of good HTTP friendly REST applications are easy and simple to
build. As this framework grows we will likely incorporate larger and more opinionated
building blocks to make development even easier.

Currently Jackalope does offer a built-in CRUD service for managing a collection of
resources in a uniform way. The services take a schema, typically one that extends the
'jackalope/rest/service/crud' schema, and a resource repository and creates a web service
with the following features.

- listing
- This is done by doing a GET to the URI of a collection (/)
- The result is a list of resources, each with embedded hypermedia controls
- It returns a 200 (OK) status code
- TODO:
- This should take search params and paging params as well
- creation
- Creation is done by doing a POST to the specified creation URI (/) with the body of a resource as the content
- The newly created resource is returned in the body of the response
- the resource will include links that provide hrefs for the various other actions
- It returns a 201 (Created) status code
- the response Location header provides the link to read the resource
- read
- Reading is done by doing a GET the specified reading URI (/:id) with the ID for the resource embedded in the URL
- The resource is returned in the body of the response
- It returns a 200 (OK) status code
- If the resource is not found it returns a 404 (Not Found) status code
- update
- Updating is done by doing a PUT to the specified update URI (/:id) with ...
- The resource id embedded in the URL
- You need to PUT the full wrapped resource (minus the links metadata) so that it can test the version string to make sure it is in sync
- the updated resource is sent back in the body of the request
- It returns a 202 (Accepted) status code
- If the resource is not found it returns a 404 (Not Found) status code
- If the resource is out of sync (versions don't match), a 409 (Conflict) status is returned with no content
- If the ID in the URL does not match the ID in the resource, a 400 (Bad Request) status is returned with no content
- delete
- deletion is done by doing a DELETE to the specified deletion URI (/:id) with the ID for the resource embedded in the URL
- It returns a 204 (No Content) status code
- An optional If-Matches header is supported for version checking
- it should contain the version string of the resource you want to delete and we will check it against the current one before deletion
- if it does not match it returns a 409 (Conflict) status with no content

We also check to make sure that the proper HTTP method is used for the proper
URI and throw a 405 (Method Not Allowed) error with an 'Allow' header properly
populated.
# Jackalope-JS

A Javascript implementation of Jackalope as well as UI components for
interaction with Jackalope web services

## Installation

Expand All @@ -187,33 +16,11 @@ To install this module type the following:

This module requires these other modules and libraries:

Moose
MooseX::Getopt
MooseX::Types::Path::Class
MooseX::Params::Validate
Bread::Board
Throwable::Error
Plack
JSON::XS
Try::Tiny
Class::Load
Clone
Digest
File::Spec::Unix
List::AllUtils
Data::Visitor::Callback
Scalar::Util
Data::Peek
Data::Dumper
Devel::PartialDump
Template
FindBin
Jackalope

Test::More
Test::Moose
Test::Fatal
Test::Builder
HTTP::Request::Common

## Copyright and License

Expand All @@ -226,12 +33,7 @@ it under the same terms as Perl itself.

## References

* [Richardson Maturity Model](http://martinfowler.com/articles/richardsonMaturityModel.html)
* [REST in Practice](http://restinpractice.com/default.aspx)
* [REST on Wikipedia](http://en.wikipedia.org/wiki/Representational_State_Transfer)
* [ATOM publishing protocol](http://www.atomenabled.org/)
* [HTTP Status Codes](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
* [Link relations](http://www.iana.org/assignments/link-relations/link-relations.xhtml)
* [Cannonical REST Entity](http://code.msdn.microsoft.com/cannonicalRESTEntity)
* [Backbone.js](http://documentcloud.github.com/backbone/)
* [Cocoa Framework](http://developer.apple.com/technologies/mac/cocoa.html)


0 comments on commit eabe1c5

Please sign in to comment.