regal 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ddd9f8426b202a6cd710732b5d90121c1be6de3d
4
- data.tar.gz: 923b6298aeaa7086e43e3856e4a3a1cfc840037b
3
+ metadata.gz: 93df06eabeeeab76187242a2fef5943f00f44e4c
4
+ data.tar.gz: 879f67a1905fb2f50fb83d36c040533a398feebb
5
5
  SHA512:
6
- metadata.gz: 875dc13b486d7d0629ecce89564c3f26b2084a0c72fb6a98cca6ef3316527be8482d9dbfbe7b3216326afdf85e930bc7ab33bf5a672ddeb24a4077ce20efda01
7
- data.tar.gz: 47ef101e32275bacc1019a74d7a54ab040b020fc31931b92c5fd8ddee4dd9108524efa74003a167655b04a39d6e12f9ad5e06458c92ff9066da33c8cfa297f99
6
+ metadata.gz: e80aa3aebcb0af7e5a99b11394ebcae70e91fbfa86a7b6e8118479f4ab8941ae08140bf404e1ec8cf595007645694334226697c2c32ab707ccebce57767e59fd
7
+ data.tar.gz: 12ae48d478d7072c34be83383f7eb38e3c4a7da59e4a3d3e1265353f8100757303c09757c62658b6a24da8d8f3c449775a334ce72938a93cde9247b7b09feead
data/.yardopts CHANGED
@@ -1,4 +1,4 @@
1
1
  --no-private
2
2
  --markup markdown
3
3
  lib/**/*.rb
4
- -- README
4
+ -- README
data/README.md ADDED
@@ -0,0 +1,145 @@
1
+ # Regal ♔
2
+
3
+ [![Build Status](https://travis-ci.org/iconara/regal.png?branch=master)](https://travis-ci.org/iconara/regal)
4
+ [![Coverage Status](https://coveralls.io/repos/iconara/regal/badge.png)](https://coveralls.io/r/iconara/regal)
5
+ [![Blog](http://b.repl.ca/v1/blog-regal-ff69b4.png)](http://architecturalatrocities.com/tagged/regal)
6
+
7
+ _If you're reading this on GitHub, please note that this is the readme for the development version and that some features described here might not yet have been released. You can find the readme for a specific version either through [rubydoc.info](http://rubydoc.info/find/gems?q=regal) or via the release tags ([here is an example](https://github.com/iconara/regal/tree/v0.1.0))._
8
+
9
+ Regal is a Rack framework where you model your application as a tree of routes.
10
+
11
+ ## Just give me an example already
12
+
13
+ Stick this in a `config.ru` and `rackup`:
14
+
15
+ ```ruby
16
+ require 'regal'
17
+ require 'json'
18
+
19
+ # Regal apps are classes, so you can create multiple
20
+ # instances of them with different configuration
21
+ ThingsApp = Regal::App.create do
22
+ # you build your app up by defining routes, these
23
+ # map directly to the request path, so this route
24
+ # matches requests that begin with /things
25
+ route 'things' do
26
+ # a route can have a handler for each HTTP method, these
27
+ # are passed request and response objects, but unless you
28
+ # need them you can leave those out, like this one does
29
+ #
30
+ # the response is what is returned from the handler, but
31
+ # below you will see how to make sure it's formatted properly
32
+ get do |request|
33
+ # when you create an instance of an app you can give it a hash,
34
+ # a copy of this hash is available through request.attributes,
35
+ # and is shared between all before, after and rescue blocks, as
36
+ # well as the handler blocks, like here
37
+ request.attributes[:database].values
38
+ end
39
+
40
+ # this handler uses both the request and the response
41
+ post do |request, response|
42
+ # request bodies are easily available
43
+ thing = JSON.load(request.body.read)
44
+ request.attributes[:database].store(thing['name'], thing)
45
+ # this is how you set the response code and headers
46
+ response.status = 201
47
+ response.headers['Location'] = '/things'
48
+ # the handler's return value will be set as response body
49
+ thing
50
+ end
51
+
52
+ # routes with symbols are wildcards and capture their value, so for the
53
+ # path /things/bees the parameter `:thing` will get the value "bees"
54
+ route :thing do
55
+ # helper methods don't need to be defined in special `helper` blocks,
56
+ # they can be defined like this
57
+ #
58
+ # they are available in all child routes, but not sibling routes
59
+ def find_thing(database, name)
60
+ database.fetch(name)
61
+ end
62
+
63
+ # rescue_from works a bit like regular rescue, if any before or after
64
+ # block, or handler in this or any child route raises an error, the
65
+ # first matching `rescue_from` block will be called – and unless it
66
+ # re-raises the error it is assumed to have been handled and the after
67
+ # blocks will be called
68
+ rescue_from KeyError do |error, request, response|
69
+ response.status = 404
70
+ response.body = {'error' => 'Thing not found'}
71
+ end
72
+
73
+ # before blocks run before the handler and can inspect the request
74
+ # and stop the request processing by calling #finish on the response
75
+ before do |request, response|
76
+ thing = find_thing(request.attributes[:database], request.parameters[:thing])
77
+ if thing
78
+ # before blocks can communicate with other before blocks, handlers
79
+ # and after blocks by setting request attributes
80
+ #
81
+ # it might look like this is a way to share things between requests,
82
+ # but each request has its own copy, so anything you add is only
83
+ # going to be accessible during the request
84
+ #
85
+ # you're of course allowed to put mutable objects in the attributes,
86
+ # like this app's `:database`, which makes it possible to share
87
+ # things between requests
88
+ request.attributes[:thing] = thing
89
+ else
90
+ response.status = 404
91
+ response.body = {'error' => 'Not Found'}
92
+ # finish will stop all remaining before blocks and the handler
93
+ # from running, but after blocks (see below) will still run
94
+ response.finish
95
+ end
96
+ end
97
+
98
+ get do |request|
99
+ # this will not run if a before block stops the request processing
100
+ # and it can access anything that the before blocks have put in
101
+ # the attributes hash
102
+ request.attributes[:thing]
103
+ end
104
+ end
105
+ end
106
+
107
+ # this handler is defined at the top level, I just defined it down here
108
+ # because it's not very important in this app, the order doesn't matter
109
+ get do |request, response|
110
+ response.headers['Location'] = '/things'
111
+ response.status = 302
112
+ # when you don't want to send any body you can call #no_body on the
113
+ # response, it doesn't matter where you do it, it doesn't have to be last
114
+ response.no_body
115
+ end
116
+
117
+ # after all of the request handling has been done the after blocks are called
118
+ # and they get to do whatever they like with the response, for example
119
+ # turning it into JSON, like this
120
+ after do |request, response|
121
+ response.headers['Content-Type'] = 'application/json'
122
+ response.body = JSON.pretty_generate(response.body) << "\n"
123
+ end
124
+ end
125
+
126
+ # to run your app with Rack you need to create an instance,
127
+ # the arguments you pass here are available as request.attributes
128
+ run ThingsApp.new(database: {})
129
+ ```
130
+
131
+ You can do lots more with Regal, check out the tests to see more.
132
+
133
+ # How to contribute
134
+
135
+ [See CONTRIBUTING.md](CONTRIBUTING.md)
136
+
137
+ # Regal?
138
+
139
+ Besides being the Rack framework for kings and queens, the name can be roughly translated from German as "rack".
140
+
141
+ # Copyright
142
+
143
+ Copyright 2015 Theo Hultberg/Iconara and contributors.
144
+
145
+ _Licensed under the BSD 3-Clause license see [http://opensource.org/licenses/BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause)_