rackful 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/CHANGES.md +30 -0
  2. data/RACKFUL.md +159 -0
  3. data/rackful.gemspec +3 -3
  4. metadata +8 -6
data/CHANGES.md ADDED
@@ -0,0 +1,30 @@
1
+ 0.1.x
2
+ =====
3
+ The 0.1.x series is a major revision, not backward compatible with 0.0.x.
4
+
5
+ 0.1.1
6
+ -----
7
+ * Fixed the gemspec file. Not everything new was properly included (including
8
+ this changelog!).
9
+
10
+ 0.1.0
11
+ -----
12
+ * Complete revision of the {Rackful::HTTPStatus} exception class. From now on,
13
+ there's
14
+ a separate class for each HTTP status code, e.g. {Rackful::HTTP404NotFound}.
15
+ * {Rackful::Path}, a subclass of `String`, is used for HTTP paths. This allows
16
+ serializers, especially for hypermedia, to distinguish paths from "ordinary"
17
+ strings, and render them accordingly.
18
+ * The concept of {Rackful::Serializer Serializers} was introduced. A serializer
19
+ is an object that knows how to serialize an object to a certain media type.
20
+ * The mechanism for content negotiation has changed completely. See
21
+ {Rackful::Resource#serializer} and {Rackful::Resource::ClassMethods#best_content_type}.
22
+ * The mechanism for implementing HTTP method handlers has changed. See
23
+ {Rackful::Resource#do_METHOD} and {Rackful::Resource::ClassMethods#add_parser}.
24
+
25
+ 0.0.x
26
+ =====
27
+
28
+ 0.0.2
29
+ -----
30
+ * Improved documentation
data/RACKFUL.md ADDED
@@ -0,0 +1,159 @@
1
+ Rackful
2
+ =======
3
+
4
+ Library for creating Rackful web services
5
+
6
+ The latest documentation is always available
7
+ [here, as GitHub pages](http://pieterb.github.com/Rackful/).
8
+
9
+ Rationale
10
+ ---------
11
+
12
+ Confronted with the task of implementing a Rackful web service in Ruby, I
13
+ checked out a number of existing libraries and frameworks, including
14
+ Ruby-on-Rails, and then decided to brew my own, the reason being that I couldn't
15
+ find a library or framework with all of the following properties:
16
+
17
+ * **Small** Some of these frameworks are really big. I need to get a job done in
18
+ time. If understanding the framework takes more time than writing my own, I
19
+ must at least feel confident that the framework I'm learning is more powerful
20
+ that what I can come up with by myself. Ruby-on-Rails is probably the biggest
21
+ framework out there, and it still lacks many features that are essential to
22
+ Rackful web service programming.
23
+
24
+ This library is small. You could read _all_ the source code in less than an
25
+ hour, and understand every detail.
26
+
27
+ * **No extensive tooling or code generation** Code generation has been the
28
+ subject of more than one flame-war over the years. Not much I can add to the
29
+ debate...
30
+
31
+ _...but,_ with Ruby, you shouldn't _need_ code generation!
32
+ Unless, of course, you're an ex-Java programmer and/or don't understand
33
+ meta-programming.
34
+
35
+ * **Full support for conditional requests** using `If-*:` request headers. Most
36
+ libraries' support is limited to `If-None-Match:` and `If-Modified-Since:`
37
+ headers, and only for `GET` and `HEAD` requests. For Rackful web services,
38
+ the `If-Match:` and `If-Unmodified-Since:` headers are at least as important,
39
+ particularly for unsafe methods like `PUT`, `POST`, `PATCH`, and `DELETE`.
40
+
41
+ This library fully supports the `ETag:` and `Last-Modified:` headers, and all
42
+ `If-*:` headers.
43
+
44
+ * **Resource centered** Some libraries claim Rackfulness, but at the same
45
+ time have a servet-like interface, which requires you to implement method
46
+ handles such as `doPOST(url)`. In these method handlers you have to find out
47
+ what resource is posted to, depending on the URL.
48
+
49
+ This library requires that you implement a Resource Factory which maps URIs
50
+ to resource Objects. These objects will then receive HTTP requests.
51
+
52
+ Hello World!
53
+ ------------
54
+
55
+ Here's a working example of a simple Rackful server:
56
+
57
+ {include:file:example/config.ru}
58
+
59
+ This file is included in the distribution as `example/config.ru`.
60
+ If you go to the `example` directory and run `rackup`, you should see
61
+ something like this:
62
+
63
+ $> rackup
64
+ [2012-07-10 11:45:32] INFO WEBrick 1.3.1
65
+ [2012-07-10 11:45:32] INFO ruby 1.9.2 (2011-12-27) [java]
66
+ [2012-07-10 11:45:32] INFO WEBrick::HTTPServer#start: pid=5994 port=9292
67
+
68
+ Go with your browser to {http://localhost:9292/} and be greeted.
69
+
70
+ In this example, we implement `GET` and `PUT` requests for the resource at '/'. but
71
+ we get a few things for free:
72
+
73
+ ### Free `OPTIONS` response:
74
+
75
+ Request:
76
+
77
+ OPTIONS / HTTP/1.1
78
+ Host: localhost:9292
79
+
80
+ Response:
81
+
82
+ HTTP/1.1 204 No Content
83
+ Allow: PUT, GET, HEAD, OPTIONS
84
+ Date: Tue, 10 Jul 2012 10:22:52 GMT
85
+
86
+ As you can see, the server accurately reports all available methods for the
87
+ resource. Notice the availability of the `HEAD` method; if you implement the
88
+ `GET` method, you'll get `HEAD` for free. It's still a good idea to explicitly
89
+ implement your own `HEAD` request handler, especially for expensive resources,
90
+ when responding to a `HEAD` request should be much more efficient than generating
91
+ a full `GET` response, and strip off the response body.
92
+
93
+ ### Free conditional request handling:
94
+
95
+ Let's first get the current state of the resource, with this request:
96
+
97
+ GET / HTTP/1.1
98
+ Host: localhost:9292
99
+
100
+ Response:
101
+
102
+ HTTP/1.1 200 OK
103
+ Content-Type: text/plain
104
+ Content-Length: 12
105
+ ETag: "86fb269d190d2c85f6e0468ceca42a20"
106
+ Date: Tue, 10 Jul 2012 10:34:36 GMT
107
+
108
+ Hello world!
109
+
110
+ Now, we'd like to change the state of the resource, but only if it's still in
111
+ the state we last saw, to avoid the "lost update problem". To do that, we
112
+ produce an `If-Match:` header, with the entity tag of our last version:
113
+
114
+ PUT / HTTP/1.1
115
+ Host: localhost:9292
116
+ Content-Type: text/plain
117
+ Content-Length: 31
118
+ If-Match: "86fb269d190d2c85f6e0468ceca42a20"
119
+
120
+ All your base are belong to us.
121
+
122
+ Response:
123
+
124
+ HTTP/1.1 204 No Content
125
+ ETag: "920c1e9267f923c62b55a471c1d8a528"
126
+ Date: Tue, 10 Jul 2012 10:58:57 GMT
127
+
128
+ The response contains an `ETag:` header, with the _new_ entity tag of this
129
+ resource. When we replay this request, we get the following response:
130
+
131
+ HTTP/1.1 412 Precondition Failed
132
+ Content-Type: text/html; charset="UTF-8"
133
+ Date: Tue, 10 Jul 2012 11:06:54 GMT
134
+
135
+ [...]
136
+ <h1>HTTP/1.1 412 Precondition Failed</h1>
137
+ <p>If-Match: "86fb269d190d2c85f6e0468ceca42a20"</p>
138
+ [...]
139
+
140
+ The server returns with status <tt>412 Precondition Failed</tt>. In the HTML
141
+ response body, the server kindly points out exactly which precondition.
142
+
143
+ Further reading
144
+ ---------------
145
+ * {Rackful::Server#initialize} for more information about your Resource Factory.
146
+ * {Rackful::Resource#get_etag} and {Rackful::Resource#get_last_modified} for more information on
147
+ conditional requests.
148
+ * {Rackful::Resource#do_METHOD} for more information about writing your own request
149
+ handlers.
150
+ * {Rackful::RelativeLocation} for more information about this piece of Rack middleware
151
+ which allows you to return relative and absolute paths in the `Location:`
152
+ response header, and why you'd want that.
153
+
154
+ Licensing
155
+ ---------
156
+ Copyright ©2011-2012 Pieter van Beek <pieterb@sara.nl>
157
+
158
+ Licensed under the Apache License 2.0. You should have received a copy of the
159
+ license as part of this distribution.
data/rackful.gemspec CHANGED
@@ -2,7 +2,7 @@ Gem::Specification.new do |s|
2
2
 
3
3
  # Required properties:
4
4
  s.name = 'rackful'
5
- s.version = '0.1.0'
5
+ s.version = '0.1.1'
6
6
  s.summary = "Library for building ReSTful web services with Rack"
7
7
  s.description = <<EOS
8
8
  Rackful provides a minimal interface for developing ReSTful web services with
@@ -11,8 +11,8 @@ resource objects, which expose their state at URLs.
11
11
 
12
12
  This version is NOT backward compatible with versions 0.0.x.
13
13
  EOS
14
- s.files = Dir[ '{example/*,lib/**/*}' ] +
15
- %w( rackful.gemspec README.md LICENSE.md mkdoc.sh )
14
+ s.files = Dir[ '{*.md,example/*,lib/**/*}' ] +
15
+ %w( rackful.gemspec mkdoc.sh )
16
16
 
17
17
  # Optional properties:
18
18
  s.author = 'Pieter van Beek'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rackful
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-04 00:00:00.000000000Z
12
+ date: 2012-08-05 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
16
- requirement: &70130076580680 !ruby/object:Gem::Requirement
16
+ requirement: &70177120280540 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '1.4'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70130076580680
24
+ version_requirements: *70177120280540
25
25
  description: ! 'Rackful provides a minimal interface for developing ReSTful web services
26
26
  with
27
27
 
@@ -38,6 +38,10 @@ executables: []
38
38
  extensions: []
39
39
  extra_rdoc_files: []
40
40
  files:
41
+ - CHANGES.md
42
+ - LICENSE.md
43
+ - RACKFUL.md
44
+ - README.md
41
45
  - example/config.ru
42
46
  - example/config2.ru
43
47
  - lib/rackful/header_spoofing.rb
@@ -51,8 +55,6 @@ files:
51
55
  - lib/rackful_serializer.rb
52
56
  - lib/rackful_server.rb
53
57
  - rackful.gemspec
54
- - README.md
55
- - LICENSE.md
56
58
  - mkdoc.sh
57
59
  homepage: http://pieterb.github.com/Rackful/
58
60
  licenses: