daylight 0.9.0.rc1
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 +7 -0
- data/README.md +113 -0
- data/app/controllers/daylight_documentation/documentation_controller.rb +27 -0
- data/app/helpers/daylight_documentation/documentation_helper.rb +57 -0
- data/app/views/daylight_documentation/documentation/_header.haml +4 -0
- data/app/views/daylight_documentation/documentation/index.haml +12 -0
- data/app/views/daylight_documentation/documentation/model.haml +114 -0
- data/app/views/layouts/documentation.haml +22 -0
- data/config/routes.rb +8 -0
- data/doc/actions.md +70 -0
- data/doc/benchmarks.md +17 -0
- data/doc/contribute.md +80 -0
- data/doc/develop.md +1205 -0
- data/doc/environment.md +109 -0
- data/doc/example.md +3 -0
- data/doc/framework.md +31 -0
- data/doc/install.md +128 -0
- data/doc/principles.md +42 -0
- data/doc/testing.md +107 -0
- data/doc/usage.md +970 -0
- data/lib/daylight/api.rb +293 -0
- data/lib/daylight/associations.rb +247 -0
- data/lib/daylight/client_reloader.rb +45 -0
- data/lib/daylight/collection.rb +161 -0
- data/lib/daylight/errors.rb +94 -0
- data/lib/daylight/inflections.rb +7 -0
- data/lib/daylight/mock.rb +282 -0
- data/lib/daylight/read_only.rb +88 -0
- data/lib/daylight/refinements.rb +63 -0
- data/lib/daylight/reflection_ext.rb +67 -0
- data/lib/daylight/resource_proxy.rb +226 -0
- data/lib/daylight/version.rb +10 -0
- data/lib/daylight.rb +27 -0
- data/rails/daylight/api_controller.rb +354 -0
- data/rails/daylight/documentation.rb +13 -0
- data/rails/daylight/helpers.rb +32 -0
- data/rails/daylight/params.rb +23 -0
- data/rails/daylight/refiners.rb +186 -0
- data/rails/daylight/server.rb +29 -0
- data/rails/daylight/tasks.rb +37 -0
- data/rails/extensions/array_ext.rb +9 -0
- data/rails/extensions/autosave_association_fix.rb +49 -0
- data/rails/extensions/has_one_serializer_ext.rb +111 -0
- data/rails/extensions/inflections.rb +6 -0
- data/rails/extensions/nested_attributes_ext.rb +94 -0
- data/rails/extensions/read_only_attributes.rb +35 -0
- data/rails/extensions/render_json_meta.rb +99 -0
- data/rails/extensions/route_options.rb +47 -0
- data/rails/extensions/versioned_url_for.rb +22 -0
- data/spec/config/dependencies.rb +2 -0
- data/spec/config/factory_girl.rb +4 -0
- data/spec/config/simplecov_rcov.rb +26 -0
- data/spec/config/test_api.rb +1 -0
- data/spec/controllers/documentation_controller_spec.rb +24 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +24 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/daylight.rb +1 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +59 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/helpers/documentation_helper_spec.rb +82 -0
- data/spec/lib/daylight/api_spec.rb +178 -0
- data/spec/lib/daylight/associations_spec.rb +325 -0
- data/spec/lib/daylight/collection_spec.rb +235 -0
- data/spec/lib/daylight/errors_spec.rb +111 -0
- data/spec/lib/daylight/mock_spec.rb +144 -0
- data/spec/lib/daylight/read_only_spec.rb +118 -0
- data/spec/lib/daylight/refinements_spec.rb +80 -0
- data/spec/lib/daylight/reflection_ext_spec.rb +50 -0
- data/spec/lib/daylight/resource_proxy_spec.rb +325 -0
- data/spec/rails/daylight/api_controller_spec.rb +421 -0
- data/spec/rails/daylight/helpers_spec.rb +41 -0
- data/spec/rails/daylight/params_spec.rb +45 -0
- data/spec/rails/daylight/refiners_spec.rb +178 -0
- data/spec/rails/extensions/array_ext_spec.rb +51 -0
- data/spec/rails/extensions/has_one_serializer_ext_spec.rb +135 -0
- data/spec/rails/extensions/nested_attributes_ext_spec.rb +177 -0
- data/spec/rails/extensions/render_json_meta_spec.rb +140 -0
- data/spec/rails/extensions/route_options_spec.rb +309 -0
- data/spec/rails/extensions/versioned_url_for_spec.rb +46 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/support/migration_helper.rb +40 -0
- metadata +422 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: a160432a89b2031c5897592fcf570c6de41cef69
|
|
4
|
+
data.tar.gz: 52b800d5206e184a13cb0eaf1dc721b4af820897
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9b5aa0bfa3e0524fc7d2b86052fb7137bbcdd75c86d21d34346b89cf81240c4311f2b5554b2d56144f2f0565a0668e9ef8c7939e1f815e50b17ee6a7a67deae1
|
|
7
|
+
data.tar.gz: e97de04202276572bd099e6b9244b840087110effa934d73949b11150714e3f21ccff519ed119f70817cb60bb2b0691612c1daf97ecfd01a80d0470c1cc8bd72
|
data/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Daylight
|
|
2
|
+
|
|
3
|
+
Daylight extends Rails and ActiveResource to allow your client API to perform
|
|
4
|
+
akin to ActiveRecord
|
|
5
|
+
|
|
6
|
+
Features include those like ActiveRecord such as scopes, `find_by` lookups,
|
|
7
|
+
calling associations on server-side models, using through associations, and
|
|
8
|
+
the ability to chain queries. Eases requesting complex queries on your Rails
|
|
9
|
+
models using `remoted` methods.
|
|
10
|
+
|
|
11
|
+
Typical ActiveResource functionality:
|
|
12
|
+
|
|
13
|
+
````ruby
|
|
14
|
+
API::Post.all # index request
|
|
15
|
+
API::Post.published # client-based association
|
|
16
|
+
API::Post.find(1) # show request
|
|
17
|
+
````
|
|
18
|
+
|
|
19
|
+
Daylight adds to ActiveResource with chained queries:
|
|
20
|
+
|
|
21
|
+
````ruby
|
|
22
|
+
API::Post.where(author_id: 1) # simple query
|
|
23
|
+
API::Post.where(author_id: 1).first # chained query
|
|
24
|
+
API::Post.where(author_id: 1).published # chained query with scope
|
|
25
|
+
API::Post.where(author_id: 1).published.recent # chained query with multiple scopes
|
|
26
|
+
API::Post.where(author_id: 1).limit(10).offset(20) # chained query with limit and offset
|
|
27
|
+
API::Post.where(author_id: 1).order(:date) # chained query with ordering
|
|
28
|
+
|
|
29
|
+
API::Post.find_by(slug: '100-best-albums-2014') # find_by lookup gets first match
|
|
30
|
+
````
|
|
31
|
+
|
|
32
|
+
Daylight can also chain queries on an ActiveResource's association. All of the
|
|
33
|
+
chain queries above can be used to refine searches on associations:
|
|
34
|
+
|
|
35
|
+
````ruby
|
|
36
|
+
API::Post.first.comments # lookup and association
|
|
37
|
+
API::Post.first.comments.where(user_id: 2) # query on lookup's association
|
|
38
|
+
API::Post.first.comments.where(user_id: 2).first # chained query on
|
|
39
|
+
API::Post.first.comments.where(user_id: 2).edited # chained query with scope
|
|
40
|
+
# etc.
|
|
41
|
+
````
|
|
42
|
+
|
|
43
|
+
Daylight allows you to return collections from complex queries on your model:
|
|
44
|
+
|
|
45
|
+
````ruby
|
|
46
|
+
API::Post.first.top_comments
|
|
47
|
+
````
|
|
48
|
+
|
|
49
|
+
Daylight packages API query details in one request when it can to lower
|
|
50
|
+
the network overhead.
|
|
51
|
+
|
|
52
|
+
Daylight allows you to query for a record before initializing or creating it
|
|
53
|
+
using ActiveRecord's familiar `first_or_create` and `first_or_initialize`
|
|
54
|
+
methods.
|
|
55
|
+
|
|
56
|
+
````ruby
|
|
57
|
+
post = API::Post.new(slug: '100-best-albums-2014')
|
|
58
|
+
post.author = API::User.find_or_create(username: 'reidmix')
|
|
59
|
+
post.save
|
|
60
|
+
````
|
|
61
|
+
|
|
62
|
+
The last query to the database uses Rails' `accepts_nested_attributes_for`
|
|
63
|
+
and the `User` could have easily been setup with `find_or_initialize` to
|
|
64
|
+
reduce the number of server-side queries.
|
|
65
|
+
|
|
66
|
+
More information can be found in the [Daylight Users Guide](doc/usage.md).
|
|
67
|
+
|
|
68
|
+
## Getting Started
|
|
69
|
+
|
|
70
|
+
1. Install Daylight both on your server and your client.
|
|
71
|
+
|
|
72
|
+
gem install daylight
|
|
73
|
+
|
|
74
|
+
2. On your server, add a rails initializer:
|
|
75
|
+
|
|
76
|
+
````ruby
|
|
77
|
+
require 'daylight/server'
|
|
78
|
+
````
|
|
79
|
+
|
|
80
|
+
3. On your client, setup your API:
|
|
81
|
+
|
|
82
|
+
````ruby
|
|
83
|
+
Daylight::API.setup!(endpoint: 'http://localhost/')
|
|
84
|
+
````
|
|
85
|
+
|
|
86
|
+
4. Use your client models to query your API!
|
|
87
|
+
|
|
88
|
+
## Development
|
|
89
|
+
|
|
90
|
+
Ah, but we have to develop our API and client models:
|
|
91
|
+
|
|
92
|
+
1. Develop your Rails models, controllers, and routes like you do today. Add
|
|
93
|
+
a serializer for each model in the API. Daylight provides additions to
|
|
94
|
+
simplify adding features to your controllers and routes.
|
|
95
|
+
|
|
96
|
+
2. Develop your client models using Daylight's extensions to ActiveResource.
|
|
97
|
+
Daylight provides Mocks to aid in full stack testing of your client models.
|
|
98
|
+
|
|
99
|
+
3. Consider versioning your client models and distribute them using a gem.
|
|
100
|
+
Daylight supports versioned APIs and has facilities available for your
|
|
101
|
+
development.
|
|
102
|
+
|
|
103
|
+
4. More information can be found on:
|
|
104
|
+
* [Installation Steps](doc/install.md)
|
|
105
|
+
* [Daylight Users Guide](doc/usage.md)
|
|
106
|
+
* [API Developer Guide](doc/develop.md)
|
|
107
|
+
* [Testing Your API](doc/testing.md)
|
|
108
|
+
* [How to Contribute](doc/contribute.md)
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
Daylight is released under the [Apache License](http://www.apache.org/licenses/LICENSE-2.0).
|
|
113
|
+
First released on June 30th, 2014.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Controller that handles rendering the API Documentation
|
|
3
|
+
class DaylightDocumentation::DocumentationController < ActionController::Base
|
|
4
|
+
layout 'documentation'
|
|
5
|
+
|
|
6
|
+
caches_page :index, :model
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
# Index of all the models/endpoints
|
|
10
|
+
def index
|
|
11
|
+
@models = models
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Model description
|
|
16
|
+
def model
|
|
17
|
+
model_name = params[:model]
|
|
18
|
+
@model = models.find { |model| model.name.underscore == model_name }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def models
|
|
24
|
+
Rails.application.eager_load!
|
|
25
|
+
ActiveRecord::Base.descendants
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Helper methods for rendering the endpoint/model documentation.
|
|
3
|
+
module DaylightDocumentation::DocumentationHelper
|
|
4
|
+
|
|
5
|
+
ACTION_DEFINITIONS = {
|
|
6
|
+
'index' => "Retrieves a list of %{names}",
|
|
7
|
+
'create' => "Creates a new %{name}",
|
|
8
|
+
'show' => "Retrieves a %{name} by an ID",
|
|
9
|
+
'update' => "Updates a %{name}",
|
|
10
|
+
'associated' => "Returns %{name}\'s %{associated}",
|
|
11
|
+
'remoted' => "Calls %{name}\'s remote method %{remoted}"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Yield all of the route information for the given model.
|
|
16
|
+
#
|
|
17
|
+
# Yields route verb (GET, POST, etc), path specification, route defaults
|
|
18
|
+
def model_verbs_and_routes(model)
|
|
19
|
+
routes = Daylight::Documentation.routes.routes.select {|route| route.path.spec.to_s.include? "/#{model.name.underscore.pluralize}" }
|
|
20
|
+
|
|
21
|
+
routes.each do |route|
|
|
22
|
+
yield route_verb(route), route.path.spec, route.defaults
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
# A list of all the possible filters for the given model.
|
|
28
|
+
def model_filters(model)
|
|
29
|
+
model.attribute_names + model.reflection_names
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# A description of a route given the route defaults and model class.
|
|
34
|
+
def action_definition(defaults, model)
|
|
35
|
+
ACTION_DEFINITIONS[defaults[:action]] % {
|
|
36
|
+
name: model.name.titleize.downcase,
|
|
37
|
+
names: model.name.titleize.pluralize.downcase,
|
|
38
|
+
associated: defaults[:associated].to_s.pluralize.tr('_', ' '),
|
|
39
|
+
remoted: defaults[:remoted]
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def client_namespace
|
|
44
|
+
Daylight::API.namespace
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def api_version
|
|
48
|
+
Daylight::API.version.downcase
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def route_verb(route)
|
|
54
|
+
%w[GET POST PUT PATCH DELETE].find {|verb| verb =~ route.verb}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
- content_for :title, "#{Daylight::API.namespace} :: API"
|
|
2
|
+
|
|
3
|
+
.container
|
|
4
|
+
|
|
5
|
+
.page-header
|
|
6
|
+
%h1 Models
|
|
7
|
+
|
|
8
|
+
.row
|
|
9
|
+
- @models.sort_by(&:name).each_slice(1+@models.count/3) do |group|
|
|
10
|
+
.list-group.col-md-3
|
|
11
|
+
- group.each do |model|
|
|
12
|
+
=link_to model.name, model_path(model.name.underscore), class: 'list-group-item'
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
- content_for :title, "#{client_namespace} :: #{@model.name} API"
|
|
2
|
+
|
|
3
|
+
.container
|
|
4
|
+
|
|
5
|
+
.row
|
|
6
|
+
|
|
7
|
+
.col-md-9
|
|
8
|
+
.page-header
|
|
9
|
+
%h1= @model.name
|
|
10
|
+
|
|
11
|
+
#api.panel.panel-default
|
|
12
|
+
.panel-heading
|
|
13
|
+
%h3 API
|
|
14
|
+
%table.table.table-condensed
|
|
15
|
+
- model_verbs_and_routes(@model) do |verb, path, defaults|
|
|
16
|
+
%tr
|
|
17
|
+
%td= defaults[:action].capitalize
|
|
18
|
+
%td= verb
|
|
19
|
+
%td= path
|
|
20
|
+
%td= action_definition(defaults, @model)
|
|
21
|
+
|
|
22
|
+
#filters.panel.panel-default
|
|
23
|
+
.panel-heading
|
|
24
|
+
%h3.panel-title Filters
|
|
25
|
+
.panel-body
|
|
26
|
+
%ul.list-inline
|
|
27
|
+
- model_filters(@model).each do |filter|
|
|
28
|
+
%li.btn.btn-default= filter
|
|
29
|
+
|
|
30
|
+
- attribute = @model.attribute_names.second
|
|
31
|
+
%h4 API Examples
|
|
32
|
+
%pre
|
|
33
|
+
== /#{api_version}/#{@model.name.underscore.pluralize}.json?filters[#{attribute}]=foo
|
|
34
|
+
|
|
35
|
+
%h4 Client Examples
|
|
36
|
+
%pre
|
|
37
|
+
== #{client_namespace}::#{@model.name}.where(#{attribute}: 'foo')
|
|
38
|
+
|
|
39
|
+
- scopes = @model.registered_scopes
|
|
40
|
+
- if scopes.present?
|
|
41
|
+
#scopes.panel.panel-default
|
|
42
|
+
.panel-heading
|
|
43
|
+
%h3.panel-title Scopes
|
|
44
|
+
|
|
45
|
+
.panel-body
|
|
46
|
+
%ul.list-group
|
|
47
|
+
- scopes.each do |scope|
|
|
48
|
+
%li.list-group-item= "#{@model.name}.#{scope}"
|
|
49
|
+
|
|
50
|
+
%h4 API Examples
|
|
51
|
+
%pre
|
|
52
|
+
==/#{api_version}/#{@model.name.underscore.pluralize}.json?scopes[]=#{scopes.first}
|
|
53
|
+
- if scopes.count > 1
|
|
54
|
+
%br<>
|
|
55
|
+
== /#{api_version}/#{@model.name.underscore.pluralize}.json?scopes[]=#{scopes.first}&scopes[]=#{scopes.last}
|
|
56
|
+
|
|
57
|
+
%h4 Client Examples
|
|
58
|
+
%pre
|
|
59
|
+
== #{client_namespace}::#{@model.name}.#{scopes.first}
|
|
60
|
+
- if scopes.count > 1
|
|
61
|
+
%br<>
|
|
62
|
+
== #{client_namespace}::#{@model.name}.#{scopes.first}.#{scopes.last}
|
|
63
|
+
|
|
64
|
+
#associations.panel.panel-default
|
|
65
|
+
.panel-heading
|
|
66
|
+
%h3.panel-title Associations
|
|
67
|
+
.panel-body
|
|
68
|
+
%ul.list-group
|
|
69
|
+
- @model.reflections.each_pair do |key, reflection|
|
|
70
|
+
%li.list-group-item
|
|
71
|
+
%a{title: reflection.klass.name, href: "#{reflection.klass.name.downcase}.html"}= reflection.name
|
|
72
|
+
|
|
73
|
+
- reflections = @model.reflection_names.grep /s$/
|
|
74
|
+
- if reflections.present?
|
|
75
|
+
%h4 API Examples
|
|
76
|
+
%pre
|
|
77
|
+
==/#{api_version}/#{@model.name.underscore.pluralize}/1/#{reflections.first}.json
|
|
78
|
+
|
|
79
|
+
%h4 Client Examples
|
|
80
|
+
%pre
|
|
81
|
+
==#{@model.name.underscore}.#{reflections.first}
|
|
82
|
+
|
|
83
|
+
#client-examples.panel.panel-default
|
|
84
|
+
.panel-heading
|
|
85
|
+
%h3.panel-title Other Client Examples
|
|
86
|
+
.panel-body
|
|
87
|
+
%pre
|
|
88
|
+
#{client_namespace}::#{@model.name}.first
|
|
89
|
+
%br<>
|
|
90
|
+
#{client_namespace}::#{@model.name}.find(1)
|
|
91
|
+
- reflection = @model.reflections.values.find {|ref| ref.macro == :has_many }
|
|
92
|
+
- if reflection
|
|
93
|
+
%br<>
|
|
94
|
+
#{client_namespace}::#{@model.name}.find(1).#{reflection.name}
|
|
95
|
+
%br<>
|
|
96
|
+
#{client_namespace}::#{@model.name}.find(1).#{reflection.name} << #{client_namespace}::#{reflection.klass.name}.find(2)
|
|
97
|
+
- filter = reflection.klass.attribute_names.last
|
|
98
|
+
%br<>
|
|
99
|
+
#{client_namespace}::#{@model.name}.find(1).#{reflection.name}.where(#{filter}: filter_value)
|
|
100
|
+
%br<>
|
|
101
|
+
#{client_namespace}::#{@model.name}.find(1).#{reflection.name}.where(#{filter}: filter_value).first_or_create
|
|
102
|
+
|
|
103
|
+
#navigation.col-md-3
|
|
104
|
+
%ul.nav.nav-pills.nav-stacked.affix
|
|
105
|
+
%li.active
|
|
106
|
+
%a{href:'#api'} API
|
|
107
|
+
%li
|
|
108
|
+
%a{href:'#filters'} Filters
|
|
109
|
+
%li
|
|
110
|
+
%a{href:'#scopes'} Scopes
|
|
111
|
+
%li
|
|
112
|
+
%a{href:'#associations'} Associations
|
|
113
|
+
%li
|
|
114
|
+
%a{href:'#client-examples'} Client Examples
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
!!! 5
|
|
2
|
+
%html
|
|
3
|
+
%head
|
|
4
|
+
%meta{charset: "utf-8"}
|
|
5
|
+
%meta{name: "viewport", content: "width=device-width, initial-scale=1"}
|
|
6
|
+
|
|
7
|
+
%link{rel: "stylesheet", href: "https://netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css"}
|
|
8
|
+
%script{src: "https://code.jquery.com/jquery-1.10.1.min.js"}
|
|
9
|
+
%script{src: "https://netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"}
|
|
10
|
+
|
|
11
|
+
%title= yield :title
|
|
12
|
+
|
|
13
|
+
:css
|
|
14
|
+
.spacer20 { height: 20px; width: 100%; font-size: 0; margin: 0; padding: 0; border: 0; display: block; }
|
|
15
|
+
.spacer50 { height: 50px; width: 100%; font-size: 0; margin: 0; padding: 0; border: 0; display: block; }
|
|
16
|
+
.btn-lg { font-size: 40px; }
|
|
17
|
+
|
|
18
|
+
%body{:'data-spy' => "scroll", :'data-target' => "#navigation"}
|
|
19
|
+
|
|
20
|
+
= render 'header'
|
|
21
|
+
|
|
22
|
+
= yield
|
data/config/routes.rb
ADDED
data/doc/actions.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Controller Actions
|
|
2
|
+
|
|
3
|
+
When your `APIController` handles all requests, like so:
|
|
4
|
+
|
|
5
|
+
````ruby
|
|
6
|
+
|
|
7
|
+
class PostController < APIController
|
|
8
|
+
handles :all
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
````
|
|
12
|
+
|
|
13
|
+
Essentially, these are the actions that are run on its behalf:
|
|
14
|
+
|
|
15
|
+
````ruby
|
|
16
|
+
|
|
17
|
+
class PostController < APIController
|
|
18
|
+
|
|
19
|
+
# GET /posts.json
|
|
20
|
+
#
|
|
21
|
+
def index
|
|
22
|
+
render json: Post.refine_by(params)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# POST /posts.json
|
|
27
|
+
#
|
|
28
|
+
def create
|
|
29
|
+
@post = Post.new(params[:post])
|
|
30
|
+
@post.save!
|
|
31
|
+
|
|
32
|
+
render json: @post, status: :created, location: @post
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# GET /posts/1.json
|
|
36
|
+
#
|
|
37
|
+
def show
|
|
38
|
+
render json: Post.find(params[:id])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# PATCH/PUT /posts/1.json
|
|
42
|
+
#
|
|
43
|
+
def update
|
|
44
|
+
Post.find(params[:id]).update!(params[:post])
|
|
45
|
+
|
|
46
|
+
head :no_content
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# DELETE /posts/1.json
|
|
50
|
+
#
|
|
51
|
+
def destroy
|
|
52
|
+
Post.find(params[:id]).destroy
|
|
53
|
+
|
|
54
|
+
head :no_content
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# GET /posts/1/comments.json
|
|
58
|
+
#
|
|
59
|
+
def associated
|
|
60
|
+
render json: Post.associated(params), root: associated_params
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# GET /posts/1/all_authorized_users.json
|
|
64
|
+
#
|
|
65
|
+
def remoted
|
|
66
|
+
render json: Post.remoted(params), root: remoted_params
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
````
|
data/doc/benchmarks.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Benchmarks
|
|
2
|
+
|
|
3
|
+
Placeholder to show benchmarks of `Daylight` requests and responses.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## LOC Statistics
|
|
7
|
+
|
|
8
|
+
As an exercise we look at the lines of code at the time of writing this
|
|
9
|
+
documentation. Excluding comments and empty lines, `Daylight` is really
|
|
10
|
+
tiny:
|
|
11
|
+
|
|
12
|
+
| Where | LOC |
|
|
13
|
+
| ---------- | ---: |
|
|
14
|
+
| Client | 490 |
|
|
15
|
+
| Server | 507 |
|
|
16
|
+
| Mock | 174 |
|
|
17
|
+
| **Total** | 1171 |
|
data/doc/contribute.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Daylight: the intial release. We encourage you to contribute, explore
|
|
4
|
+
our new framework, to seek out strange new bugs and build new possiblities,
|
|
5
|
+
to boldly go where we have not gone before.
|
|
6
|
+
|
|
7
|
+
## History
|
|
8
|
+
|
|
9
|
+
Daylight was built as an API for a web application on the AT&T Cloud team
|
|
10
|
+
using the domain model needed for several tasks in the organization. We
|
|
11
|
+
wanted to be able to lift sections of our codebase out of the monolithic
|
|
12
|
+
codebase with little-to-no code changes between `ActiveRecord` and
|
|
13
|
+
`ActiveResource`.
|
|
14
|
+
|
|
15
|
+
The functionality was built for the organization's usecases and while
|
|
16
|
+
documenting, we've noticed "holes" or possiblities within the codebase.
|
|
17
|
+
|
|
18
|
+
Daylight is the extracted files that sat between our API models and the
|
|
19
|
+
Rails components. We've also extracted some of our tools such as the
|
|
20
|
+
mocking framework we built and Documentation Rails engine with hopes
|
|
21
|
+
that they might serve useful to API developers.
|
|
22
|
+
|
|
23
|
+
Daylight is named as such for our intent the framework would be able to
|
|
24
|
+
"_see the light of day_".
|
|
25
|
+
|
|
26
|
+
## Reporting an Issue
|
|
27
|
+
|
|
28
|
+
We are using Github's [Issues](https://github.com/att-cloud/daylight/issues)
|
|
29
|
+
to track all future work and bugs. Please investigate if there is a bug
|
|
30
|
+
already submitted for your the issue you've found and if not, submit a
|
|
31
|
+
[new issue](https://github.com/att-cloud/daylight/issues/new).
|
|
32
|
+
|
|
33
|
+
Include a title and a clear statement of a problem. If you can, add the
|
|
34
|
+
steps to reproduce, a backtrace, the Daylight gem version as well as the
|
|
35
|
+
Rails & ActiveModelSerializer version numbers. Please include example
|
|
36
|
+
code when possible.
|
|
37
|
+
|
|
38
|
+
## Contributing to the Codebase
|
|
39
|
+
|
|
40
|
+
Daylight is a self-contained, running rspec tests against a _dummy_ Rails
|
|
41
|
+
application backed by a sqlite database. Once you have your
|
|
42
|
+
[build Environment](environment.md) up and running, you will be able to
|
|
43
|
+
run the tests.
|
|
44
|
+
|
|
45
|
+
Clone (or fork) the Daylight repository:
|
|
46
|
+
|
|
47
|
+
$ git clone git://github.com/att-cloud/daylight.git
|
|
48
|
+
|
|
49
|
+
Switch to your own branch:
|
|
50
|
+
|
|
51
|
+
$ cd daylight
|
|
52
|
+
$ git checkout -b my_branch
|
|
53
|
+
|
|
54
|
+
Build your code and tests. Ensure they all run, see if you a missing any
|
|
55
|
+
tests:
|
|
56
|
+
|
|
57
|
+
$ cd daylight
|
|
58
|
+
$ rake spec
|
|
59
|
+
$ rake rcov
|
|
60
|
+
|
|
61
|
+
Commit your changes:
|
|
62
|
+
|
|
63
|
+
$ git commit -a
|
|
64
|
+
|
|
65
|
+
Issue a [pull request](#https://help.github.com/articles/using-pull-requests)
|
|
66
|
+
using your branch with your code changes.
|
|
67
|
+
|
|
68
|
+
## Understanding
|
|
69
|
+
|
|
70
|
+
To better understand how a framework extends or alters the underlying Rails
|
|
71
|
+
technology and help navigate the code for contributing, here are details and
|
|
72
|
+
guidelines on how Daylight was built.
|
|
73
|
+
|
|
74
|
+
Please rely on the following for reference or feel free to ask or suggest
|
|
75
|
+
improvements:
|
|
76
|
+
|
|
77
|
+
* [Guiding Principles](principles.md)
|
|
78
|
+
* [Build Environment](environment.md)
|
|
79
|
+
* [Framework Overview](framework.md)
|
|
80
|
+
* [Daylight Benchmarks](benchmarks.md)
|