sinja 1.1.0.pre4 → 1.2.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -1
- data/README.md +96 -29
- data/demo-app/.dockerignore +1 -0
- data/demo-app/Dockerfile +26 -0
- data/demo-app/Gemfile +12 -1
- data/demo-app/README.md +39 -24
- data/demo-app/Rakefile +36 -0
- data/demo-app/app.rb +3 -10
- data/demo-app/boot.rb +0 -4
- data/demo-app/classes/author.rb +3 -4
- data/demo-app/{base.rb → classes/base.rb} +2 -1
- data/demo-app/classes/comment.rb +1 -2
- data/demo-app/classes/post.rb +17 -10
- data/demo-app/classes/tag.rb +7 -3
- data/extensions/sequel/Gemfile +4 -0
- data/extensions/sequel/LICENSE.txt +21 -0
- data/extensions/sequel/README.md +274 -0
- data/extensions/sequel/Rakefile +10 -0
- data/extensions/sequel/bin/console +14 -0
- data/extensions/sequel/bin/setup +8 -0
- data/extensions/sequel/lib/sinatra/jsonapi/sequel.rb +7 -0
- data/extensions/sequel/lib/sinja-sequel.rb +2 -0
- data/extensions/sequel/lib/sinja/sequel.rb +110 -0
- data/extensions/sequel/lib/sinja/sequel/core.rb +72 -0
- data/extensions/sequel/lib/sinja/sequel/helpers.rb +78 -0
- data/extensions/sequel/lib/sinja/sequel/version.rb +6 -0
- data/extensions/sequel/sinja-sequel.gemspec +29 -0
- data/extensions/sequel/test/test_helper.rb +3 -0
- data/lib/sinja.rb +40 -18
- data/lib/sinja/config.rb +4 -3
- data/lib/sinja/helpers/serializers.rb +2 -1
- data/lib/sinja/relationship_routes/has_many.rb +8 -9
- data/lib/sinja/relationship_routes/has_one.rb +1 -1
- data/lib/sinja/resource.rb +2 -1
- data/lib/sinja/resource_routes.rb +2 -2
- data/lib/sinja/version.rb +1 -1
- data/sinja.gemspec +5 -7
- metadata +39 -11
- data/.rspec +0 -2
- data/lib/sinja/extensions/sequel.rb +0 -53
- data/lib/sinja/helpers/sequel.rb +0 -101
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7194e1502968ad1c77f29a86eba2142a02e9fab0
|
4
|
+
data.tar.gz: d60c872b2a8b8d5555f18eb2a3064fd748ab4ec8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a42b7e9f8c15e748145b731f9329c7bcce307fb4224ba1f33c2172faacb41fd75dcebe02374e9aa6101fef422f8d12bf09f1c32fdfb4b2a45239e97bd28643c1
|
7
|
+
data.tar.gz: ec35d6bd75b8b47b03ad9a6803407f03ca5c89593389962820de22c1a63de6c7ce7309b592264e8ac961ad552547658ff8723eeac22f8a0f1b8b628cd3c8a9da
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,18 @@
|
|
1
1
|
# Sinja (Sinatra::JSONAPI)
|
2
2
|
|
3
|
+
<!--
|
4
|
+
Title: Sinja
|
5
|
+
Description: RESTful, {json:api}-compliant web services in Sinatra
|
6
|
+
Author: Mike Pastore
|
7
|
+
Keywords: JSON, API, JSONAPI, JSON:API, {json:api}, Ruby, Sinatra, JSONAPI::Serializers, jsonapi-serializers
|
8
|
+
-->
|
9
|
+
|
3
10
|
[](https://badge.fury.io/rb/sinja)
|
11
|
+
[](https://gemnasium.com/github.com/mwpastore/sinja)
|
4
12
|
[](https://travis-ci.org/mwpastore/sinja)
|
5
|
-
|
13
|
+
|
14
|
+
[](https://gitter.im/sinja-rb/Lobby)
|
15
|
+
[](https://ember-community-slackin.herokuapp.com/?channel=-ember-data)
|
6
16
|
|
7
17
|
Sinja is a [Sinatra][1] [extension][10] for quickly building [RESTful][11],
|
8
18
|
[{json:api}][2]-[compliant][7] web services, leveraging the excellent
|
@@ -26,6 +36,7 @@ the {json:api} specification is).
|
|
26
36
|
- [Commonly Used](#commonly-used)
|
27
37
|
- [Less-Commonly Used](#less-commonly-used)
|
28
38
|
- [Performance](#performance)
|
39
|
+
- [Extensions](#extensions)
|
29
40
|
- [Comparison with JSONAPI::Resources](#comparison-with-jsonapiresources)
|
30
41
|
- [Basic Usage](#basic-usage)
|
31
42
|
- [Configuration](#configuration)
|
@@ -48,6 +59,7 @@ the {json:api} specification is).
|
|
48
59
|
- [`has_many`](#has_many)
|
49
60
|
- [`fetch {..}` => Array](#fetch---array)
|
50
61
|
- [`clear {..}` => TrueClass?](#clear---trueclass)
|
62
|
+
- [`replace {|rios| ..}` => TrueClass?](#replace-rios---trueclass)
|
51
63
|
- [`merge {|rios| ..}` => TrueClass?](#merge-rios---trueclass)
|
52
64
|
- [`subtract {|rios| ..}` => TrueClass?](#subtract-rios---trueclass)
|
53
65
|
- [Advanced Usage](#advanced-usage)
|
@@ -346,6 +358,13 @@ written them verbosely. The main caveat is that there are quite a few block
|
|
346
358
|
closures, which don't perform as well as normal methods in Ruby. Feedback
|
347
359
|
welcome.
|
348
360
|
|
361
|
+
### Extensions
|
362
|
+
|
363
|
+
Sinja extensions provide additional helpers, DSL, and configuration, packaging
|
364
|
+
ORM-specific boilerplate as separate gems. At the moment, the only available
|
365
|
+
extension is for [Sequel](/extensions/sequel), but community contributions are
|
366
|
+
welcome!
|
367
|
+
|
349
368
|
### Comparison with JSONAPI::Resources
|
350
369
|
|
351
370
|
| Feature | JR | Sinja |
|
@@ -436,7 +455,7 @@ configure_jsonapi do |c|
|
|
436
455
|
|
437
456
|
# You can't set this directly; see "Query Parameters" below
|
438
457
|
#c.query_params = {
|
439
|
-
# :include=>[], :fields=>{}, :filter=>{}, :page=>{}, :sort=>
|
458
|
+
# :include=>[], :fields=>{}, :filter=>{}, :page=>{}, :sort=>[]
|
440
459
|
#}
|
441
460
|
|
442
461
|
#c.page_using = {} # see "Paging" below
|
@@ -630,6 +649,18 @@ has_many :bars do
|
|
630
649
|
end
|
631
650
|
```
|
632
651
|
|
652
|
+
##### `replace {|rios| ..}` => TrueClass?
|
653
|
+
|
654
|
+
Take an array of [resource identifier object][22] hashes and update
|
655
|
+
(add/remove) the relationships on `resource`. To serialize the updated linkage
|
656
|
+
on the response, refresh or reload `resource` (if necessary) and return a
|
657
|
+
truthy value.
|
658
|
+
|
659
|
+
In principle, `replace` should delete all members of the existing collection
|
660
|
+
and insert all members of a new collection, but in practice—for
|
661
|
+
performance reasons, especially with large collections and/or complex
|
662
|
+
constraints—it may be prudent to simply apply a delta.
|
663
|
+
|
633
664
|
##### `merge {|rios| ..}` => TrueClass?
|
634
665
|
|
635
666
|
Take an array of [resource identifier object][22] hashes and update (add unless
|
@@ -735,6 +766,7 @@ configure_jsonapi do |c|
|
|
735
766
|
c.default_has_many_roles = {
|
736
767
|
fetch: :user,
|
737
768
|
clear: :admin,
|
769
|
+
replace: :admin,
|
738
770
|
merge: :admin,
|
739
771
|
subtract: :admin
|
740
772
|
}
|
@@ -835,8 +867,8 @@ resource :foos do
|
|
835
867
|
end
|
836
868
|
end
|
837
869
|
|
838
|
-
create(roles: :user) {
|
839
|
-
update(roles: :owner) {
|
870
|
+
create(roles: :user) {|attr| .. }
|
871
|
+
update(roles: :owner) {|attr| .. }
|
840
872
|
end
|
841
873
|
```
|
842
874
|
|
@@ -934,7 +966,7 @@ For example, to implement sorting using Sequel:
|
|
934
966
|
```ruby
|
935
967
|
helpers do
|
936
968
|
def sort(collection, fields={})
|
937
|
-
collection.order(*fields.map {
|
969
|
+
collection.order(*fields.map {|k, v| Sequel.send(v, k) })
|
938
970
|
end
|
939
971
|
end
|
940
972
|
|
@@ -968,7 +1000,7 @@ Allow clients to page the collections returned by the `index` and `fetch`
|
|
968
1000
|
action helpers by defining a `page` helper in the appropriate scope that takes
|
969
1001
|
a collection and a hash of `page` query parameters (with its top-level keys
|
970
1002
|
dedasherized and symbolized) and returns the paged collection along with a
|
971
|
-
special nested hash used to build the paging links.
|
1003
|
+
special nested hash used as root metadata and to build the paging links.
|
972
1004
|
|
973
1005
|
The top-level keys of the hash returned by this method must be members of the
|
974
1006
|
set: {`:self`, `:first`, `:prev`, `:next`, `:last`}. The values of the hash are
|
@@ -1000,8 +1032,8 @@ Could be used to build the following top-level links in the response document:
|
|
1000
1032
|
You must also set the `page_using` configurable to a hash of symbols
|
1001
1033
|
representing the paging fields used in your application (for example, `:number`
|
1002
1034
|
and `:size` for the above example) along with their default values (or `nil`).
|
1003
|
-
Please see the [Sequel
|
1004
|
-
|
1035
|
+
Please see the [Sequel extension](/extensions/sequel) in this repository for a
|
1036
|
+
detailed, working example.
|
1005
1037
|
|
1006
1038
|
The easiest way to page a collection by default is to tweak the post-processed
|
1007
1039
|
query parameter(s) in a `before_<action>` hook:
|
@@ -1036,10 +1068,6 @@ helpers do
|
|
1036
1068
|
end
|
1037
1069
|
```
|
1038
1070
|
|
1039
|
-
(Note that in addition to finalizing Sequel datasets with `#all`, you should
|
1040
|
-
also enable the `:tactical_eager_loading` plugin for the best compatibility
|
1041
|
-
with JSONAPI::Serializers.)
|
1042
|
-
|
1043
1071
|
### Conflicts
|
1044
1072
|
|
1045
1073
|
If your database driver raises exceptions on constraint violations, you should
|
@@ -1174,12 +1202,11 @@ request will fail and any database changes will be rolled back (given a
|
|
1174
1202
|
`transaction` helper). Note that the user's role must grant them access to call
|
1175
1203
|
either `graft` or `create`.
|
1176
1204
|
|
1177
|
-
`create` and `update` are the
|
1178
|
-
`graft
|
1205
|
+
`create` and `update` are the resource action helpers that trigger sideloading;
|
1206
|
+
`graft` and `prune` are the to-one action helpers invoked by sideloading; and
|
1207
|
+
`replace`, `merge`, and `clear` are the to-many action helpers invoked by
|
1179
1208
|
sideloading. You must indicate which combinations are valid using the
|
1180
|
-
`:sideload_on` action helper option.
|
1181
|
-
on `update`, you must define a `clear` action helper and allow it to sideload
|
1182
|
-
on `update` as well.) For example:
|
1209
|
+
`:sideload_on` action helper option. For example:
|
1183
1210
|
|
1184
1211
|
```ruby
|
1185
1212
|
resource :photos do
|
@@ -1187,24 +1214,64 @@ resource :photos do
|
|
1187
1214
|
def find(id) ..; end
|
1188
1215
|
end
|
1189
1216
|
|
1190
|
-
create {
|
1191
|
-
update { |attr| .. }
|
1217
|
+
create {|attr| .. }
|
1192
1218
|
|
1193
1219
|
has_one :photographer do
|
1194
|
-
# Allow `create' to sideload
|
1195
|
-
graft(sideload_on: :create) {
|
1220
|
+
# Allow `create' to sideload Photographer
|
1221
|
+
graft(sideload_on: :create) {|rio| .. }
|
1196
1222
|
end
|
1197
1223
|
|
1198
1224
|
has_many :tags do
|
1199
|
-
# Allow `create'
|
1200
|
-
merge(sideload_on:
|
1201
|
-
|
1202
|
-
# Allow `update' to clear Tags before sideloading them
|
1203
|
-
clear(sideload_on: :update) { .. }
|
1225
|
+
# Allow `create' to sideload Tags
|
1226
|
+
merge(sideload_on: :create) {|rios| .. }
|
1204
1227
|
end
|
1205
1228
|
end
|
1206
1229
|
```
|
1207
1230
|
|
1231
|
+
The following matrix outlines which combinations of action helpers and
|
1232
|
+
`:sideload_on` options enable which behaviors:
|
1233
|
+
|
1234
|
+
<small>
|
1235
|
+
<table>
|
1236
|
+
<thead>
|
1237
|
+
<tr>
|
1238
|
+
<th rowspan="2">Desired behavior</th>
|
1239
|
+
<th colspan="2">For to-one relationship(s)</th>
|
1240
|
+
<th colspan="2">For to-many relationship(s)</th>
|
1241
|
+
</tr>
|
1242
|
+
<tr>
|
1243
|
+
<th>Define Action Helper</th>
|
1244
|
+
<th>With <code>:sideload_on</code></th>
|
1245
|
+
<th>Define Action Helper</th>
|
1246
|
+
<th>With <code>:sideload_on</code></th>
|
1247
|
+
</tr>
|
1248
|
+
</thead>
|
1249
|
+
<tbody>
|
1250
|
+
<tr>
|
1251
|
+
<td>Set relationship(s) when creating resource</td>
|
1252
|
+
<td><code>graft</code></td>
|
1253
|
+
<td><code>:create</code></td>
|
1254
|
+
<td><code>merge</code></td>
|
1255
|
+
<td><code>:create</code></td>
|
1256
|
+
</tr>
|
1257
|
+
<tr>
|
1258
|
+
<td>Set relationship(s) when updating resource</td>
|
1259
|
+
<td><code>graft</code></td>
|
1260
|
+
<td><code>:update</code></td>
|
1261
|
+
<td><code>replace</code></td>
|
1262
|
+
<td><code>:update</code></td>
|
1263
|
+
</tr>
|
1264
|
+
<tr>
|
1265
|
+
<td>Delete relationship(s) when updating resource</td>
|
1266
|
+
<td><code>prune</code></td>
|
1267
|
+
<td><code>:update</code></td>
|
1268
|
+
<td><code>clear</code></td>
|
1269
|
+
<td><code>:update</code></td>
|
1270
|
+
</tr>
|
1271
|
+
</tbody>
|
1272
|
+
</table>
|
1273
|
+
</small>
|
1274
|
+
|
1208
1275
|
#### Avoiding Null Foreign Keys
|
1209
1276
|
|
1210
1277
|
Now, let's say our DBA is forward-thinking and wants to make the foreign key
|
@@ -1271,9 +1338,9 @@ end
|
|
1271
1338
|
```
|
1272
1339
|
|
1273
1340
|
Note that the `validate!` hook is _only_ invoked from within transactions
|
1274
|
-
involving the `create` and `update` action helpers (and any
|
1275
|
-
|
1276
|
-
appropriate in those cases. You must use immedate validation in all other
|
1341
|
+
involving the `create` and `update` action helpers (and any action helpers
|
1342
|
+
invoked via the sideloading mechanism), so this deferred validation pattern is
|
1343
|
+
only appropriate in those cases. You must use immedate validation in all other
|
1277
1344
|
cases. The `sideloaded?` helper is provided to help disambiguate edge cases.
|
1278
1345
|
|
1279
1346
|
> TODO: The following three sections are a little confusing. Rewrite them.
|
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/demo-app/Dockerfile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
FROM ruby:2.3-alpine
|
2
|
+
ARG container_port=4567
|
3
|
+
ENV container_port=$container_port
|
4
|
+
|
5
|
+
RUN apk --no-cache upgrade
|
6
|
+
RUN apk --no-cache add \
|
7
|
+
sqlite-libs
|
8
|
+
|
9
|
+
COPY Gemfile /app/
|
10
|
+
RUN apk --no-cache add --virtual build-dependencies \
|
11
|
+
build-base \
|
12
|
+
git \
|
13
|
+
ruby-dev \
|
14
|
+
sqlite-dev \
|
15
|
+
&& cd /app \
|
16
|
+
&& DOCKER_BUILD=true bundle install --jobs=4 \
|
17
|
+
&& apk del build-dependencies
|
18
|
+
|
19
|
+
COPY . /app
|
20
|
+
RUN chown -R nobody:nogroup /app
|
21
|
+
|
22
|
+
USER nobody
|
23
|
+
WORKDIR /app
|
24
|
+
CMD bundle exec ruby app.rb -o 0.0.0.0 -p $container_port
|
25
|
+
|
26
|
+
EXPOSE $container_port
|
data/demo-app/Gemfile
CHANGED
@@ -1,3 +1,14 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
3
|
+
gem 'json', '~> 2.0'
|
4
|
+
gem 'sequel', '~> 4.41'
|
5
|
+
gem 'sinatra', '>= 2.0.0.beta2', '< 3'
|
6
|
+
gem 'sinatra-contrib', '>= 2.0.0.beta2', '< 3'
|
7
|
+
unless ENV.key?('DOCKER_BUILD')
|
8
|
+
gem 'sinja', path: '..'
|
9
|
+
gem 'sinja-sequel', path: '../extensions/sequel'
|
10
|
+
else
|
11
|
+
gem 'sinja'
|
12
|
+
gem 'sinja-sequel'
|
13
|
+
end
|
14
|
+
gem 'sqlite3', '~> 1.3'
|
data/demo-app/README.md
CHANGED
@@ -1,38 +1,51 @@
|
|
1
1
|
## Demo App
|
2
2
|
|
3
|
-
This is the demo app for Sinja,
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
This is the demo app for Sinja, provided both as an example of and for testing
|
4
|
+
Sinja. It uses [Sequel ORM](http://sequel.jeremyevans.net) with an in-memory
|
5
|
+
SQLite database and demonstrates the [Sequel extension](/extensions/sequel) for
|
6
|
+
Sinja. It works under both MRI/YARV 2.3+ and JRuby 9.1+. It is a very
|
7
|
+
simplistic blog-like application with [database
|
8
|
+
tables](http://sequel.jeremyevans.net/rdoc/files/doc/schema_modification_rdoc.html),
|
9
|
+
[models](http://sequel.jeremyevans.net/rdoc/files/README_rdoc.html#label-Sequel+Models),
|
10
|
+
[serializers](https://github.com/fotinakis/jsonapi-serializers), and
|
11
|
+
[controllers](/) for [authors](/demo-app/classes/author.rb),
|
12
|
+
[posts](/demo-app/classes/post.rb), [comments](/demo-app/classes/comment.rb),
|
13
|
+
and [tags](/demo-app/classes/tag.rb).
|
9
14
|
|
10
15
|
### Usage
|
11
16
|
|
12
|
-
Assuming you have a working, Bundler-enabled Ruby
|
13
|
-
this repo, `cd` into the `demo-app` subdirectory, and
|
14
|
-
commands:
|
17
|
+
Assuming you have a working, [Bundler](http://bundler.io)-enabled Ruby
|
18
|
+
environment, simply clone this repo, `cd` into the `demo-app` subdirectory, and
|
19
|
+
run the following commands:
|
15
20
|
|
16
21
|
```
|
17
22
|
$ bundle install
|
18
23
|
$ bundle exec ruby app.rb [-p <PORT>]
|
19
24
|
```
|
20
25
|
|
21
|
-
The web server will report the port it's listening on
|
22
|
-
port with the `-p` option.
|
23
|
-
(don't forget to set an `Accept` header) to `/authors`, `/posts`, `/comments`,
|
24
|
-
and `/tags`, although not every endpoint is implemented. Log in by setting the
|
25
|
-
`X-Email` header on the request to the email address of a registered user; the
|
26
|
-
default administrator email address is all@yourbase.com.
|
26
|
+
The web server will report the port it's listening on (most likely 4567), or
|
27
|
+
you can specify a port with the `-p` option.
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
Alternatively, if you don't want to clone this repo and set up a Ruby
|
30
|
+
environment just for a quick demo, it's available on Docker Cloud as
|
31
|
+
[mwpastore/sinja-demo-app](https://cloud.docker.com/app/mwpastore/repository/docker/mwpastore/sinja-demo-app):
|
32
|
+
|
33
|
+
```
|
34
|
+
$ docker run -it -p 4567:4567 --rm mwpastore/sinja-demo-app
|
35
|
+
```
|
36
|
+
|
37
|
+
It will respond to {json:api}-compliant requests (don't forget to set an
|
38
|
+
`Accept` header) to `/authors`, `/posts`, `/comments`, and `/tags`, although
|
39
|
+
not every endpoint is implemented. Log in by setting the `X-Email` header on
|
40
|
+
the request to the email address of a registered user; the email address for
|
41
|
+
the default admin user is all@yourbase.com. **This is clearly extremely
|
42
|
+
insecure and should not be used as-is in production. Caveat emptor.**
|
30
43
|
|
31
44
|
You can point it at a different database by setting `DATABASE_URL` in the
|
32
45
|
environment before executing `app.rb`. See the relevant [Sequel
|
33
46
|
documentation](http://sequel.jeremyevans.net/rdoc/files/doc/opening_databases_rdoc.html)
|
34
|
-
for more information. It (rather naïvely) migrates the database
|
35
|
-
startup.
|
47
|
+
for more information. It (rather naïvely) migrates the database and
|
48
|
+
creates the default admin user at startup.
|
36
49
|
|
37
50
|
### Productionalizing
|
38
51
|
|
@@ -40,18 +53,20 @@ You can certainly use this as a starting point for a production application,
|
|
40
53
|
but you will at least want to:
|
41
54
|
|
42
55
|
- [ ] Use a persistent database
|
56
|
+
- [ ] Remove or change the default admin user
|
43
57
|
- [ ] Separate the class files (e.g. `author.rb`, `post.rb`) into separate
|
44
|
-
files for
|
58
|
+
files for migrations, models, serializers, and Sinja controllers
|
45
59
|
- [ ] Create a Gemfile using the dependencies in the top-level
|
46
60
|
[gemspec](/sinja.gemspec) as a starting point
|
47
|
-
- [ ] Add authentication
|
48
|
-
|
49
|
-
|
61
|
+
- [ ] Add authentication and rewrite the `role` helper to enable the
|
62
|
+
authorization scheme. You can use the existing roles as defined or rename
|
63
|
+
them (e.g. use `:admin` instead of `:superuser`)
|
50
64
|
- [ ] Use a real application server such as [Puma](http://puma.io) or
|
51
65
|
[Passenger](https://www.phusionpassenger.com) instead of Ruby's
|
52
66
|
stdlib (WEBrick)
|
53
67
|
- [ ] Configure Sequel's connection pool (i.e. `:max_connections`) to match the
|
54
|
-
application server's thread pool (if any)
|
68
|
+
application server's thread pool (if any) size, e.g.
|
69
|
+
`Puma.cli_config.options[:max_threads]`
|
55
70
|
- [ ] Add caching directives (i.e. `cache_control`, `expires`, `last_modified`,
|
56
71
|
and `etag`) as appropriate
|
57
72
|
|
data/demo-app/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
namespace :docker do
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
IMAGE = 'mwpastore/sinja-demo-app'
|
6
|
+
NAME = SecureRandom.hex(6)
|
7
|
+
PORT = 4567
|
8
|
+
|
9
|
+
def port
|
10
|
+
%x{
|
11
|
+
docker inspect --format '{{ (index ( index .NetworkSettings.Ports "#{PORT}/tcp") 0).HostPort }}' #{NAME}
|
12
|
+
}.chomp
|
13
|
+
end
|
14
|
+
|
15
|
+
task :build do
|
16
|
+
sh "docker build --build-arg container_port=#{PORT} --no-cache -t #{IMAGE}:latest #{__dir__}"
|
17
|
+
end
|
18
|
+
|
19
|
+
task :test do
|
20
|
+
sh "docker run --rm -d -P --name #{NAME} #{IMAGE}"
|
21
|
+
sleep 5
|
22
|
+
begin
|
23
|
+
sh "curl -sf -H 'Accept: application/vnd.api+json' -I :#{port}/authors"
|
24
|
+
ensure
|
25
|
+
sh "docker stop #{NAME} >/dev/null || true"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
task push: [:build, :test] do
|
30
|
+
sh "docker push #{IMAGE}:latest"
|
31
|
+
end
|
32
|
+
|
33
|
+
task :run do
|
34
|
+
sh "docker run --rm -it -p #{PORT}:#{PORT} #{IMAGE}"
|
35
|
+
end
|
36
|
+
end
|
data/demo-app/app.rb
CHANGED
@@ -1,28 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'sinatra'
|
3
3
|
require 'sinatra/jsonapi'
|
4
|
+
require 'sinja/sequel/helpers'
|
4
5
|
|
5
6
|
require_relative 'classes/author'
|
6
7
|
require_relative 'classes/comment'
|
7
8
|
require_relative 'classes/post'
|
8
9
|
require_relative 'classes/tag'
|
9
10
|
|
10
|
-
require 'sinja/helpers/sequel'
|
11
|
-
|
12
11
|
configure :development do
|
13
12
|
set :server_settings, AccessLog: [] # avoid WEBrick double-logging issue
|
14
13
|
end
|
15
14
|
|
16
|
-
|
17
|
-
Sinja::Helpers::Sequel.config(c)
|
18
|
-
end
|
19
|
-
|
20
|
-
helpers do
|
21
|
-
prepend Sinja::Helpers::Sequel
|
22
|
-
|
15
|
+
helpers Sinja::Sequel::Helpers do
|
23
16
|
def current_user
|
24
17
|
# TESTING/DEMO PURPOSES ONLY -- DO NOT DO THIS IN PRODUCTION
|
25
|
-
Author.first_by_email(env['HTTP_X_EMAIL']) if env.key?('HTTP_X_EMAIL')
|
18
|
+
@current_user ||= Author.first_by_email(env['HTTP_X_EMAIL']) if env.key?('HTTP_X_EMAIL')
|
26
19
|
end
|
27
20
|
|
28
21
|
def role
|