mappd_rest 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 54ee288597cfd12f98eedb6fcc20ec30491688e7303f979071c4b57111d3faf6
4
+ data.tar.gz: fcb1dddabd63d63d890bf52262383ad808d653f2301ce56d7000895ad9343495
5
+ SHA512:
6
+ metadata.gz: 79b40d18e4f6d0a8ed7f31a4956b4d1cfbd662e17df26d274fb94cfd232212fc96d0648103bb1babae367e680a8e3120e9312dc50d2880f00e541cb23fbd3ade
7
+ data.tar.gz: b88f37604579a9b7eaa5f5c78388113f35946c8c1590a35fb30a64728ffa7e282b80c91c07298f5e456f16fbab688eacd6137771f98822138ff8ed32da567b84
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ tmp/
2
+ .byebug_history
3
+ db/*.db
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,15 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.5
3
+ Exclude:
4
+ - 'Guardfile'
5
+ Style/Documentation:
6
+ Enabled: false
7
+ Style/FrozenStringLiteralComment:
8
+ Enabled: false
9
+ Metrics/ModuleLength:
10
+ Exclude:
11
+ - "**/*_spec.rb"
12
+ Metrics/BlockLength:
13
+ Exclude:
14
+ - "**/*_spec.rb"
15
+ - "lib/mappd/rest.rb"
data/Dockerfile ADDED
@@ -0,0 +1,31 @@
1
+ FROM ruby:2.5-slim
2
+ MAINTAINER dan@paz.am
3
+ ENV REFRESHED_AT 2018-05-14
4
+
5
+ # Install packages
6
+ RUN apt-get update && apt-get install -y --no-install-recommends \
7
+ build-essential \
8
+ git \
9
+ ruby-dev \
10
+ libgdbm-dev \
11
+ libncurses5-dev \
12
+ libffi-dev \
13
+ libyaml-dev \
14
+ libreadline-dev \
15
+ sqlite3 \
16
+ libsqlite3-dev \
17
+ curl \
18
+ libpq-dev \
19
+ default-libmysqlclient-dev \
20
+ && rm -rf /var/lib/apt/lists/*
21
+
22
+ # Setup app location
23
+ RUN mkdir -p /app
24
+ WORKDIR /app
25
+
26
+ # Install gems
27
+ ADD mappd_rest.gemspec /app/mappd_rest.gemspec
28
+ ADD Gemfile /app/Gemfile
29
+ ADD Gemfile.lock /app/Gemfile.lock
30
+ ADD lib/ /app/lib
31
+ RUN bundle install --jobs 4
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'activerecord', '>=5.2.0'
4
+ gem 'grape', '>=1.0.3'
5
+ gem 'mappd'
6
+ gem 'rake'
7
+ gem 'sqlite3'
8
+
9
+ group :development do
10
+ gem 'byebug'
11
+ gem 'guard-rspec', require: false
12
+ gem 'guard-rubocop', require: false
13
+ gem 'rubocop', require: false
14
+ end
15
+
16
+ group :test do
17
+ gem 'rack-test'
18
+ gem 'rspec'
19
+ end
20
+
21
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,153 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mappd_rest (0.0.1)
5
+ activerecord (>= 5.2.0)
6
+ grape (>= 1.0.3)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ activemodel (5.2.0)
12
+ activesupport (= 5.2.0)
13
+ activerecord (5.2.0)
14
+ activemodel (= 5.2.0)
15
+ activesupport (= 5.2.0)
16
+ arel (>= 9.0)
17
+ activesupport (5.2.0)
18
+ concurrent-ruby (~> 1.0, >= 1.0.2)
19
+ i18n (>= 0.7, < 2)
20
+ minitest (~> 5.1)
21
+ tzinfo (~> 1.1)
22
+ arel (9.0.0)
23
+ ast (2.4.0)
24
+ axiom-types (0.1.1)
25
+ descendants_tracker (~> 0.0.4)
26
+ ice_nine (~> 0.11.0)
27
+ thread_safe (~> 0.3, >= 0.3.1)
28
+ builder (3.2.3)
29
+ byebug (10.0.2)
30
+ coderay (1.1.2)
31
+ coercible (1.0.0)
32
+ descendants_tracker (~> 0.0.1)
33
+ concurrent-ruby (1.0.5)
34
+ descendants_tracker (0.0.4)
35
+ thread_safe (~> 0.3, >= 0.3.1)
36
+ diff-lcs (1.3)
37
+ equalizer (0.0.11)
38
+ ffi (1.9.23)
39
+ formatador (0.2.5)
40
+ grape (1.0.3)
41
+ activesupport
42
+ builder
43
+ mustermann-grape (~> 1.0.0)
44
+ rack (>= 1.3.0)
45
+ rack-accept
46
+ virtus (>= 1.0.0)
47
+ guard (2.14.2)
48
+ formatador (>= 0.2.4)
49
+ listen (>= 2.7, < 4.0)
50
+ lumberjack (>= 1.0.12, < 2.0)
51
+ nenv (~> 0.1)
52
+ notiffany (~> 0.0)
53
+ pry (>= 0.9.12)
54
+ shellany (~> 0.0)
55
+ thor (>= 0.18.1)
56
+ guard-compat (1.2.1)
57
+ guard-rspec (4.7.3)
58
+ guard (~> 2.1)
59
+ guard-compat (~> 1.1)
60
+ rspec (>= 2.99.0, < 4.0)
61
+ guard-rubocop (1.3.0)
62
+ guard (~> 2.0)
63
+ rubocop (~> 0.20)
64
+ i18n (1.0.1)
65
+ concurrent-ruby (~> 1.0)
66
+ ice_nine (0.11.2)
67
+ listen (3.1.5)
68
+ rb-fsevent (~> 0.9, >= 0.9.4)
69
+ rb-inotify (~> 0.9, >= 0.9.7)
70
+ ruby_dep (~> 1.2)
71
+ lumberjack (1.0.13)
72
+ mappd (0.0.3)
73
+ activerecord (>= 5.2.0)
74
+ method_source (0.9.0)
75
+ minitest (5.11.3)
76
+ mustermann (1.0.2)
77
+ mustermann-grape (1.0.0)
78
+ mustermann (~> 1.0.0)
79
+ nenv (0.3.0)
80
+ notiffany (0.1.1)
81
+ nenv (~> 0.1)
82
+ shellany (~> 0.0)
83
+ parallel (1.12.1)
84
+ parser (2.5.1.0)
85
+ ast (~> 2.4.0)
86
+ powerpack (0.1.1)
87
+ pry (0.11.3)
88
+ coderay (~> 1.1.0)
89
+ method_source (~> 0.9.0)
90
+ rack (2.0.5)
91
+ rack-accept (0.4.5)
92
+ rack (>= 0.4)
93
+ rack-test (1.0.0)
94
+ rack (>= 1.0, < 3)
95
+ rainbow (3.0.0)
96
+ rake (12.3.1)
97
+ rb-fsevent (0.10.3)
98
+ rb-inotify (0.9.10)
99
+ ffi (>= 0.5.0, < 2)
100
+ rspec (3.7.0)
101
+ rspec-core (~> 3.7.0)
102
+ rspec-expectations (~> 3.7.0)
103
+ rspec-mocks (~> 3.7.0)
104
+ rspec-core (3.7.1)
105
+ rspec-support (~> 3.7.0)
106
+ rspec-expectations (3.7.0)
107
+ diff-lcs (>= 1.2.0, < 2.0)
108
+ rspec-support (~> 3.7.0)
109
+ rspec-mocks (3.7.0)
110
+ diff-lcs (>= 1.2.0, < 2.0)
111
+ rspec-support (~> 3.7.0)
112
+ rspec-support (3.7.1)
113
+ rubocop (0.56.0)
114
+ parallel (~> 1.10)
115
+ parser (>= 2.5)
116
+ powerpack (~> 0.1)
117
+ rainbow (>= 2.2.2, < 4.0)
118
+ ruby-progressbar (~> 1.7)
119
+ unicode-display_width (~> 1.0, >= 1.0.1)
120
+ ruby-progressbar (1.9.0)
121
+ ruby_dep (1.5.0)
122
+ shellany (0.0.1)
123
+ sqlite3 (1.3.13)
124
+ thor (0.20.0)
125
+ thread_safe (0.3.6)
126
+ tzinfo (1.2.5)
127
+ thread_safe (~> 0.1)
128
+ unicode-display_width (1.3.2)
129
+ virtus (1.0.5)
130
+ axiom-types (~> 0.1)
131
+ coercible (~> 1.0)
132
+ descendants_tracker (~> 0.0, >= 0.0.3)
133
+ equalizer (~> 0.0, >= 0.0.9)
134
+
135
+ PLATFORMS
136
+ ruby
137
+
138
+ DEPENDENCIES
139
+ activerecord (>= 5.2.0)
140
+ byebug
141
+ grape (>= 1.0.3)
142
+ guard-rspec
143
+ guard-rubocop
144
+ mappd
145
+ mappd_rest!
146
+ rack-test
147
+ rake
148
+ rspec
149
+ rubocop
150
+ sqlite3
151
+
152
+ BUNDLED WITH
153
+ 1.16.1
data/Guardfile ADDED
@@ -0,0 +1,10 @@
1
+ guard :rubocop do
2
+ watch(%r{.+\.rb$})
3
+ watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
4
+ end
5
+
6
+ guard :rspec, cmd: 'rspec' do
7
+ watch(%r{^spec/.+_spec\.rb$})
8
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
9
+ watch('spec/spec_helper.rb') { "spec" }
10
+ end
data/Makefile ADDED
@@ -0,0 +1,12 @@
1
+ build:
2
+ docker-compose build
3
+ guard:
4
+ docker-compose run ruby guard
5
+ rspec:
6
+ docker-compose run ruby rspec
7
+ lint:
8
+ docker-compose run ruby rubocop
9
+ bash:
10
+ docker-compose run ruby bash
11
+ release:
12
+
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # MappdRest
2
+
3
+ Note: Work in progress.
4
+
5
+ A gem that dynamically exposes REST endpoints for ActiveRecord models.
6
+
7
+ ## Development
8
+
9
+ ### Prerequisites
10
+
11
+ * Docker Community Edition - https://www.docker.com/community-edition
12
+ * Make - https://www.gnu.org/software/make/
13
+
14
+ ### Setup
15
+
16
+ * `make` will build the application ready for use.
17
+
18
+ ### Guard
19
+
20
+ * `make guard` run both linting and testing whilst watching files
21
+
22
+ ## Setup
23
+
24
+ ```
25
+ gem install mappd-rest
26
+ ```
27
+
28
+ Or add to your `Gemfile`:
29
+
30
+ ```
31
+ gem 'mappd-rest'
32
+ ```
33
+
34
+ ## How it works
35
+
36
+ ### Simple Endpoints
37
+
38
+ Lets say you have two ActiveRecord models. Person and Post. By either mounting the `Mappd::Rest` class inside rails or running a `config.ru` file like below the following endpoints will be created.
39
+
40
+ | METHOD | ENDPOINT |
41
+ | --- | --- |
42
+ | GET | /people/schema |
43
+ | GET | /people/ |
44
+ | GET | /people/:id |
45
+ | POST | /people |
46
+ | DELETE | /people/:id |
47
+ | PUT | /people/:id |
48
+ | GET | /post/schema |
49
+ | GET | /post/ |
50
+ | GET | /post/:id |
51
+ | POST | /post |
52
+ | DELETE | /post/:id |
53
+ | PUT | /post/:id |
54
+
55
+ ### Nested Endpoints
56
+
57
+ Also you can drive down into nested data. In this example lets say a Post has a Person and a Person has many Posts. It would create the following endpoints.
58
+
59
+
60
+ | METHOD | ENDPOINT |
61
+ | --- | --- |
62
+ | GET | /posts/:id/person |
63
+ | GET | /posts/:id/person/:id |
64
+ | GET | /posts/:id/person/:id/posts |
65
+
66
+ It does this by dynamically interpreting routes passed to the endpoint and calling the appropriate models and methods.
67
+
68
+ ### Limiting & Offsetting (Pagination)
69
+ You can also limit and offset any call that returns a collection.
70
+
71
+ `/posts?limit=10&offset=10`
72
+ `/person/1/posts?limit=5&offset=5`
73
+
74
+ ### Authorisation
75
+
76
+ Before every request the API will check for a header `X-Access-Token`
77
+ it will then use that access token as a parameter to the authorization method you have set.
78
+
79
+ ```ruby
80
+ # config.ru
81
+ Mappd::Rest.auth_method = lambda { |token|
82
+ # Will look for a truth - You can use any method you like
83
+ User.find_by_token(token).active?
84
+ # For example - if you didnt want to do any kind of auth
85
+ # just return true
86
+ }
87
+ run Mappd::Rest
88
+ ```
89
+ ## Running
90
+
91
+ ```ruby
92
+ # config.ru
93
+ run Mappd::Rest
94
+ ```
data/db/.gitkeep ADDED
File without changes
@@ -0,0 +1,11 @@
1
+ version: '2'
2
+ services:
3
+ ruby:
4
+ build:
5
+ context: .
6
+ dockerfile: Dockerfile
7
+ ports:
8
+ - '3000:3000'
9
+ volumes:
10
+ - .:/app
11
+ command: 'rackup --host 0.0.0.0 -p 3000'
data/lib/mappd/rest.rb ADDED
@@ -0,0 +1,105 @@
1
+ module Mappd
2
+ class Rest < Grape::API
3
+ format :json
4
+
5
+ cattr_accessor :auth_method
6
+
7
+ before do
8
+ unless Rest.auth_method.call(request.headers['X-Access-Token'])
9
+ error!('Access Denied', 401)
10
+ end
11
+ end
12
+
13
+ rescue_from ActiveRecord::RecordNotFound do |e|
14
+ error!(e, 404)
15
+ end
16
+
17
+ rescue_from ActiveRecord::RecordInvalid do |e|
18
+ error!(e, 422)
19
+ end
20
+
21
+ helpers do
22
+ def resource
23
+ params[:resource].singularize.titlecase.constantize
24
+ end
25
+
26
+ def all
27
+ resource.all
28
+ end
29
+
30
+ def limiter(relation)
31
+ return relation unless relation.is_a?(ActiveRecord::Relation)
32
+ relation = relation.offset(params[:offset]) if params[:offset]
33
+ relation = relation.limit(params[:limit]) if params[:limit]
34
+ relation
35
+ end
36
+
37
+ def find
38
+ resource.find(params[:id])
39
+ end
40
+
41
+ def create!(attributes)
42
+ resource.create!(attributes)
43
+ end
44
+
45
+ def update!(attributes)
46
+ find.update!(attributes)
47
+ end
48
+
49
+ def destroy!
50
+ find&.destroy
51
+ end
52
+
53
+ def method?(param)
54
+ param.to_i.to_s != param
55
+ end
56
+ end
57
+
58
+ get '/:resource/schema' do
59
+ resource.columns.map do |column|
60
+ {
61
+ name: column.name,
62
+ type: column.type.to_s
63
+ }
64
+ end
65
+ end
66
+
67
+ params do
68
+ requires :resource, type: String
69
+ optional :id, type: Integer
70
+ end
71
+
72
+ get '/:resource' do
73
+ limiter(all)
74
+ end
75
+
76
+ get '/:resource/:id' do
77
+ find
78
+ end
79
+
80
+ get '/:resource/:id/*' do
81
+ args = params[:splat][0].split('/')
82
+ relation = find
83
+ args.each_with_index do |param, index|
84
+ relation = if index.even? || method?(param)
85
+ relation.send(param.to_sym)
86
+ else
87
+ relation.find(param.to_i)
88
+ end
89
+ end
90
+ limiter(relation)
91
+ end
92
+
93
+ post '/:resource' do
94
+ create!(JSON.parse(params.first[0]))
95
+ end
96
+
97
+ put '/:resource/:id' do
98
+ update!(JSON.parse(params.first[0]))
99
+ end
100
+
101
+ delete '/:resource/:id' do
102
+ destroy!
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,3 @@
1
+ module MappdRest
2
+ VERSION = '0.0.1'.freeze
3
+ end
data/lib/mappd_rest.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'rubygems' unless defined?(Gem)
2
+ require 'bundler'
3
+ Bundler.require
4
+ require 'mappd/rest'
@@ -0,0 +1,25 @@
1
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
2
+ require 'mappd/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'mappd_rest'
6
+ s.version = MappdRest::VERSION
7
+ s.authors = ['Dan Watson']
8
+ s.email = ['dan@paz.am']
9
+ s.homepage = 'https://github.com/dan-watson/mappd-rest'
10
+ s.summary = 'Mappd Rest is a microframework for exposing ActiveRecord
11
+ models over rest'
12
+ s.description = 'You can expose ActiveRecord objects over REST.'
13
+ .gsub(/^ {4}/, '')
14
+
15
+ s.rubyforge_project = 'mappd_rest'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`
20
+ .split("\n").map { |f| File.basename(f) }
21
+ s.require_paths = ['lib']
22
+
23
+ s.add_dependency 'activerecord', '>=5.2.0'
24
+ s.add_dependency 'grape', '>=1.0.3'
25
+ end
data/spec/boot.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems' unless defined?(Gem)
2
+ require 'bundler/setup'
3
+ Bundler.require
4
+ require 'mappd_rest'
5
+
6
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3',
7
+ database: 'db/test.db')
8
+
9
+ require File.expand_path('data/data.rb', __dir__)
data/spec/crud_spec.rb ADDED
@@ -0,0 +1,114 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+ require File.expand_path('spec_helper.rb', __dir__)
3
+
4
+ require 'rack/test'
5
+ require 'byebug'
6
+
7
+ describe 'Rack Test' do
8
+ include Rack::Test::Methods
9
+
10
+ def app
11
+ Mappd::Rest.auth_method = lambda { |token|
12
+ # User.find_by_token(token)
13
+ token == 'TOKEN'
14
+ }
15
+ Mappd::Rest
16
+ end
17
+
18
+ context 'endpoints' do
19
+ before(:all) do
20
+ current_session.header 'X-Access-Token', 'TOKEN'
21
+ end
22
+
23
+ it 'returns schema for an entity' do
24
+ schema = JSON.parse(File.read('spec/data/book_schema.json'))
25
+ get '/books/schema'
26
+ expect(last_response).to be_ok
27
+ expect(JSON.parse(last_response.body)).to eq(schema)
28
+ end
29
+
30
+ it 'returns all for an entity' do
31
+ get '/books'
32
+ expect(last_response).to be_ok
33
+ expect(JSON.parse(last_response.body).length).to eq(3)
34
+ end
35
+
36
+ it 'returns two offset by one for an entity' do
37
+ get '/books?limit=2&offset=1'
38
+ expect(last_response).to be_ok
39
+ result = JSON.parse(last_response.body)
40
+ expect(result.length).to eq(2)
41
+ expect(result.map { |i| i['id'] }).to eq([2, 3])
42
+ end
43
+
44
+ it 'returns all from a relationship' do
45
+ get '/authors/1/books'
46
+ expect(last_response).to be_ok
47
+ expect(JSON.parse(last_response.body).length).to eq(2)
48
+ end
49
+
50
+ it 'returns all from a relationship with limits' do
51
+ get '/authors/1/books?limit=2&offset=1'
52
+ expect(last_response).to be_ok
53
+ expect(JSON.parse(last_response.body).length).to eq(1)
54
+ end
55
+
56
+ it 'returns one from relationship' do
57
+ get '/authors/1/books/1'
58
+ expect(last_response).to be_ok
59
+ expect(JSON.parse(last_response.body)['title'])
60
+ .to eq('Wind in the willows')
61
+ end
62
+
63
+ it 'returns one from a deeply nested relationship' do
64
+ get '/authors/1/books/1/author'
65
+ expect(last_response).to be_ok
66
+ expect(JSON.parse(last_response.body)['name'])
67
+ .to eq('Dan')
68
+ end
69
+
70
+ it 'returns one' do
71
+ get '/books/1'
72
+ expect(JSON.parse(last_response.body)['title'])
73
+ .to eq('Wind in the willows')
74
+ end
75
+
76
+ it 'does not return one' do
77
+ get '/books/600'
78
+ expect(last_response.status).to eq(404)
79
+ end
80
+
81
+ it 'creates one' do
82
+ post '/books', { title: 'New Book', year: 2012 }.to_json
83
+ expect(last_response.status).to eq(201)
84
+ expect(Book.find(3)).to be_present
85
+ end
86
+
87
+ it 'does not create one' do
88
+ post '/books', { title: 'New Book' }.to_json
89
+ expect(last_response.status).to eq(422)
90
+ end
91
+
92
+ it 'updates one' do
93
+ put '/books/1', { title: 'Updated Book', year: 2012 }.to_json
94
+ expect(last_response.status).to eq(200)
95
+ expect(Book.find(1).title).to eq('Updated Book')
96
+ end
97
+
98
+ it 'does not update one' do
99
+ put '/books/1', { title: 'Updated Book', year: nil }.to_json
100
+ expect(last_response.status).to eq(422)
101
+ end
102
+
103
+ it 'deletes one' do
104
+ delete '/books/1'
105
+ expect(last_response).to be_ok
106
+ expect { Book.find(1) }.to raise_error(ActiveRecord::RecordNotFound)
107
+ end
108
+
109
+ it 'does not delete one' do
110
+ delete '/books/600'
111
+ expect(last_response.status).to eq(404)
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,6 @@
1
+ require 'active_record'
2
+
3
+ class Author < ActiveRecord::Base
4
+ field :name, :string
5
+ has_many :books
6
+ end
data/spec/data/book.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'active_record'
2
+
3
+ class Book < ActiveRecord::Base
4
+ field :title, :string
5
+ field :year, :integer, length: 4
6
+ belongs_to :author
7
+
8
+ validates :year, presence: true
9
+ end
@@ -0,0 +1,18 @@
1
+ [
2
+ {
3
+ "name":"id",
4
+ "type":"integer"
5
+ },
6
+ {
7
+ "name":"title",
8
+ "type":"string"
9
+ },
10
+ {
11
+ "name":"year",
12
+ "type":"integer"
13
+ },
14
+ {
15
+ "name":"author_id",
16
+ "type":"integer"
17
+ }
18
+ ]
data/spec/data/data.rb ADDED
@@ -0,0 +1,16 @@
1
+ require File.expand_path('book.rb', __dir__)
2
+ require File.expand_path('author.rb', __dir__)
3
+
4
+ # Book
5
+
6
+ Book.migrate!
7
+ Author.migrate!
8
+ Book.delete_all
9
+ Author.delete_all
10
+
11
+ author = Author.create!(name: 'Dan')
12
+ author2 = Author.create!(name: 'James')
13
+
14
+ Book.create!(title: 'Wind in the willows', year: 1911, author: author)
15
+ Book.create!(title: 'Once upon a time', year: 1911, author: author)
16
+ Book.create!(title: 'Not another one', year: 2012, author: author2)
@@ -0,0 +1,18 @@
1
+ require File.expand_path('boot.rb', __dir__)
2
+
3
+ RSpec.configure do |config|
4
+ config.full_backtrace = false
5
+ config.backtrace_exclusion_patterns = [
6
+ /bundle/
7
+ ]
8
+
9
+ config.expect_with :rspec do |expectations|
10
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
11
+ end
12
+
13
+ config.mock_with :rspec do |mocks|
14
+ mocks.verify_partial_doubles = true
15
+ end
16
+
17
+ config.shared_context_metadata_behavior = :apply_to_host_groups
18
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mappd_rest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dan Watson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-05-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 5.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: grape
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.3
41
+ description: You can expose ActiveRecord objects over REST.
42
+ email:
43
+ - dan@paz.am
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - ".rspec"
50
+ - ".rubocop.yml"
51
+ - Dockerfile
52
+ - Gemfile
53
+ - Gemfile.lock
54
+ - Guardfile
55
+ - Makefile
56
+ - README.md
57
+ - db/.gitkeep
58
+ - docker-compose.yml
59
+ - lib/mappd/rest.rb
60
+ - lib/mappd/version.rb
61
+ - lib/mappd_rest.rb
62
+ - mappd_rest.gemspec
63
+ - spec/boot.rb
64
+ - spec/crud_spec.rb
65
+ - spec/data/author.rb
66
+ - spec/data/book.rb
67
+ - spec/data/book_schema.json
68
+ - spec/data/data.rb
69
+ - spec/spec_helper.rb
70
+ homepage: https://github.com/dan-watson/mappd-rest
71
+ licenses: []
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project: mappd_rest
89
+ rubygems_version: 2.7.6
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Mappd Rest is a microframework for exposing ActiveRecord models over rest
93
+ test_files: []