modern 0.4.2

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.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +8 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +173 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +10 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +36 -0
  10. data/Rakefile +10 -0
  11. data/TODOS.md +4 -0
  12. data/bin/console +9 -0
  13. data/bin/setup +8 -0
  14. data/example/Gemfile +9 -0
  15. data/example/Gemfile.lock +102 -0
  16. data/example/config.ru +11 -0
  17. data/example/example.rb +19 -0
  18. data/lib/modern/app/error_handling.rb +45 -0
  19. data/lib/modern/app/request_handling/input_handling.rb +65 -0
  20. data/lib/modern/app/request_handling/output_handling.rb +54 -0
  21. data/lib/modern/app/request_handling/request_container.rb +55 -0
  22. data/lib/modern/app/request_handling.rb +70 -0
  23. data/lib/modern/app/router.rb +27 -0
  24. data/lib/modern/app/trie_router.rb +37 -0
  25. data/lib/modern/app.rb +82 -0
  26. data/lib/modern/capsule.rb +17 -0
  27. data/lib/modern/configuration.rb +16 -0
  28. data/lib/modern/core_ext/array.rb +23 -0
  29. data/lib/modern/core_ext/hash.rb +17 -0
  30. data/lib/modern/descriptor/content.rb +14 -0
  31. data/lib/modern/descriptor/converters/input/base.rb +29 -0
  32. data/lib/modern/descriptor/converters/input/json.rb +21 -0
  33. data/lib/modern/descriptor/converters/output/base.rb +25 -0
  34. data/lib/modern/descriptor/converters/output/json.rb +48 -0
  35. data/lib/modern/descriptor/converters/output/yaml.rb +21 -0
  36. data/lib/modern/descriptor/converters.rb +4 -0
  37. data/lib/modern/descriptor/core.rb +63 -0
  38. data/lib/modern/descriptor/info.rb +27 -0
  39. data/lib/modern/descriptor/parameters.rb +149 -0
  40. data/lib/modern/descriptor/request_body.rb +13 -0
  41. data/lib/modern/descriptor/response.rb +26 -0
  42. data/lib/modern/descriptor/route.rb +93 -0
  43. data/lib/modern/descriptor/security.rb +104 -0
  44. data/lib/modern/descriptor/server.rb +12 -0
  45. data/lib/modern/descriptor.rb +15 -0
  46. data/lib/modern/doc_generator/open_api3/operations.rb +114 -0
  47. data/lib/modern/doc_generator/open_api3/paths.rb +24 -0
  48. data/lib/modern/doc_generator/open_api3/schema_default_types.rb +50 -0
  49. data/lib/modern/doc_generator/open_api3/schemas.rb +171 -0
  50. data/lib/modern/doc_generator/open_api3/security_schemes.rb +15 -0
  51. data/lib/modern/doc_generator/open_api3.rb +141 -0
  52. data/lib/modern/dsl/info.rb +39 -0
  53. data/lib/modern/dsl/response_builder.rb +41 -0
  54. data/lib/modern/dsl/root.rb +38 -0
  55. data/lib/modern/dsl/route_builder.rb +130 -0
  56. data/lib/modern/dsl/scope.rb +144 -0
  57. data/lib/modern/dsl/scope_settings.rb +39 -0
  58. data/lib/modern/dsl.rb +14 -0
  59. data/lib/modern/errors/error.rb +7 -0
  60. data/lib/modern/errors/setup_errors.rb +11 -0
  61. data/lib/modern/errors/web_errors.rb +83 -0
  62. data/lib/modern/errors.rb +3 -0
  63. data/lib/modern/redirect.rb +30 -0
  64. data/lib/modern/request.rb +34 -0
  65. data/lib/modern/response.rb +39 -0
  66. data/lib/modern/services.rb +17 -0
  67. data/lib/modern/struct.rb +25 -0
  68. data/lib/modern/types.rb +41 -0
  69. data/lib/modern/util/header_parsing.rb +27 -0
  70. data/lib/modern/util/trie_node.rb +53 -0
  71. data/lib/modern/version.rb +6 -0
  72. data/lib/modern.rb +8 -0
  73. data/manual/01-why_modern.md +115 -0
  74. data/modern.gemspec +54 -0
  75. metadata +439 -0
@@ -0,0 +1,115 @@
1
+ # What and Why? #
2
+ Modern is an API framework for Ruby web applications, built on top of Rack.
3
+
4
+ Which, by itself, isn't that much. There are a billion of these. You've got
5
+ Rails, Grape, Sinatra, and plenty more. And most of them are great! So, why then
6
+ did I feel compelled to write a new one?
7
+
8
+ A few reasons come to mind, and in describing them I hope to explain why Modern
9
+ exists and why you should use it.
10
+
11
+ ### You Shouldn't Need To Be An Expert To Do The Right Thing ###
12
+ You could call this "the right thing should be easy," too, but I feel like it's
13
+ important to dig into that a little more. Modern provides facilities to replace
14
+ a lot of the boilerplate and drudgery of other API frameworks with clean
15
+ tooling.
16
+
17
+ Modern cares about correctness. Unlike most frameworks, which have rolled their
18
+ own validation libraries (some of which are good--others of which, not so much),
19
+ Modern leverages the fantastic [dry-struct] and [dry-types] libraries to handle
20
+ easy and full-featured type declarations throughout its API. It'll test
21
+ validation of parameters and request bodies, doing the right thing (400 or 422,
22
+ as appropriate) when a problem arises--and, in development, it'll test your
23
+ response bodies against the return values you've specified, and alert you if
24
+ they don't match up.
25
+
26
+ Modern cares about security, too, and exposes to the user a simple mechanism for
27
+ securing APIs. It handles the plumbing work of pulling HTTP authorizations or
28
+ API keys out of various parameters, then hands them off to your code for proper
29
+ validation.
30
+
31
+ And Modern cares about how you're actually going to put it into production. Most
32
+ systems and frameworks are agnostic about things like request tracing or how
33
+ logging should be structured. Modern instead asserts that, yeah, you're going to
34
+ want to trace along requests to make sure everything's okay, so of course we'll
35
+ define a unique request ID (or use one if it's passed in via a HTTP request from
36
+ another service, allowing you to trace requests across many services). And
37
+ Modern also asserts that good, detailed logging is important, so its primary
38
+ logger emits structured, searchable logs courtesy of [Ougai].
39
+
40
+ ### Your Framework Shouldn't Obfuscate What You're Doing ###
41
+ A huge part of Ruby is how easy it is to build domain-specific languages to
42
+ describe the problems you're tackling. And that's fine, as far as it goes. But
43
+ the interplay between frameworks and libraries can make _what that DSL is doing_
44
+ more difficult than it needs to be to understand how your application works.
45
+
46
+ Modern is designed so that you don't _need_ a DSL. That isn't to say that a DSL
47
+ isn't useful (and `modern-dsl` is a project I'm working on as I go), but instead
48
+ that a simple, declarative object model doesn't have to be obfuscated by a
49
+ complex, sometimes even stateful (lookin' at you, Grape--carrying options
50
+ _forward_ onto the next route you declare is silly!) DSL.
51
+
52
+ Simple is good. Modern tries to be simple, and any DSL that wraps it will have
53
+ to reflect that.
54
+
55
+ ### OpenAPI Should Be First-Class ###
56
+ [OpenAPI] is awesome. I got the bug with Swagger 2.0 (now OpenAPI 2.0--the
57
+ naming is not why all of this is great) and realized that I'd wasted way too
58
+ much time building clients from scratch to talk to an API I'd knocked together
59
+ on the other end. Its tooling is great and getting better, with self-documenting
60
+ API tools and a number of generators to create clients in both dynamically typed
61
+ and statically typed languages.
62
+
63
+ Personally, I prefer to dynamically generate clients in dynamically typed
64
+ languages; [swagger-js] is kind of my thing. But reasonable people can differ.
65
+
66
+ The important thing here, though, is that Modern is designed around OpenAPI and
67
+ speaks its conventions "natively". The core object model of Modern (described in
68
+ detail later) maps easily to OpenAPI 3.0 and so an API designed along Modern's
69
+ "happy path" makes it easy to interconnect it with other systems you might run
70
+ across. You fire up your Modern app, it generates and serves an OpenAPI spec,
71
+ and you're off to the races.
72
+
73
+ ### Modern Should Be Portable ###
74
+ Obviously, I don't mean you're going to fire up Node and run `modern.rb`. But
75
+ Modern is intended to describe a fairly straightforward and _simple_ set of
76
+ behaviors that are OpenAPI-specific much more than they are Ruby-specific. It
77
+ should be eminently possible to do a side-by-side port of Modern to Node or to
78
+ Kotlin or to other languages in a way that provides baseline OpenAPI server
79
+ capabilities wherever you happen to be.
80
+
81
+ ## How Modern Works ##
82
+ Modern is a standard Rack-based application, run through a config.ru` file like
83
+ any other. There's plenty of great Rack documentation out there. Instead, let's
84
+ talk briefly about how Modern is structured, at the level you're likely to need
85
+ to know it.
86
+
87
+ The heart of your application is the **descriptor**. This object, and its children,
88
+ are an immutable declaration of "how this application runs". Routes, security
89
+ declarations, input/output converters--all of these are defined strictly by the
90
+ descriptor, which you can find in `Modern::Descriptor::Core`.
91
+
92
+ You'll also create a **configuration**, which should be an instance of type
93
+ `Modern::Configuration` or a subtype thereof if you'd like to incorporate your
94
+ own configuration data into the same object. These are operational concerns that
95
+ Modern needs to know about--whether or not to show backtraces in errors, whether
96
+ or not to validate response bodies on their way out the door, that sort of thing.
97
+
98
+ Lastly, you'll (optionally) define a set of **services**, which should be an
99
+ instance of `Modern::Services` or a subtype thereof. Here's where you'll provide
100
+ to your application the links to external "stuff", whether it's a logger or your
101
+ database or a client for a remote service. These services will be injected into
102
+ the scope of every route you write, making it easy to avoid global state or
103
+ unexpected side effects within your application.
104
+
105
+ Once you've got your descriptor, your configuration, and your services, you'll
106
+ pass them all to a constructor for `Modern::App`, which is the Rack interface
107
+ that handles your requests. It'll generate your OpenAPI documentation from your
108
+ descriptor and handle serving it, while also accepting incoming requests from
109
+ clients and dispatching them to the functional aspects of your descriptor.
110
+
111
+ [dry-struct]: http://dry-rb.org/gems/dry-struct
112
+ [dry-types]: http://dry-rb.org/gems/dry-types
113
+ [Ougai]: https://github.com/tilfin/ougai
114
+ [OpenAPI]: https://www.openapis.org
115
+ [swagger-js]: https://github.com/swagger-api/swagger-js
data/modern.gemspec ADDED
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "modern/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "modern"
9
+ spec.version = Modern::VERSION
10
+ spec.required_ruby_version = "~> 2.4"
11
+ spec.authors = ["Ed Ropple"]
12
+ spec.email = ["ed@edropple.com"]
13
+
14
+ spec.summary = "The OpenAPI-driven web framework for Ruby."
15
+ spec.homepage = "https://github.com/modern-project/modern-ruby"
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.16"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+
28
+ spec.add_development_dependency "rack-test", "~> 0.8"
29
+ spec.add_development_dependency "rspec", "~> 3.7"
30
+
31
+ spec.add_development_dependency "pry"
32
+ spec.add_development_dependency "rcodetools"
33
+ spec.add_development_dependency "rubocop"
34
+ spec.add_development_dependency "ruby-debug-ide"
35
+
36
+ spec.add_development_dependency "openapi3_parser"
37
+
38
+ spec.add_runtime_dependency "mime-types", "~> 3.1"
39
+ spec.add_runtime_dependency "mime-types-data", "~> 3.2016"
40
+ spec.add_runtime_dependency "rack", "~> 2.0"
41
+
42
+ spec.add_runtime_dependency "content-type", "~> 0.0.1"
43
+ spec.add_runtime_dependency "http", "~> 3.0"
44
+
45
+ spec.add_runtime_dependency "deep_dup", "~> 0.0.3"
46
+ spec.add_runtime_dependency "deep_merge", "~> 1.2"
47
+ spec.add_runtime_dependency "diff-lcs", "~> 1.3"
48
+ spec.add_runtime_dependency "docile", "~> 1.3"
49
+ spec.add_runtime_dependency "dry-struct", "~> 0.4"
50
+ spec.add_runtime_dependency "dry-validation", "~> 0.11"
51
+ spec.add_runtime_dependency "ice_nine", "~> 0.11.2"
52
+ spec.add_runtime_dependency "ougai", "~> 1.5"
53
+ spec.add_runtime_dependency "snake_camel", "~> 1.1"
54
+ end
metadata ADDED
@@ -0,0 +1,439 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: modern
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.2
5
+ platform: ruby
6
+ authors:
7
+ - Ed Ropple
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-03-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack-test
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rcodetools
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: ruby-debug-ide
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: openapi3_parser
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: mime-types
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '3.1'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '3.1'
153
+ - !ruby/object:Gem::Dependency
154
+ name: mime-types-data
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '3.2016'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '3.2016'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rack
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '2.0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '2.0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: content-type
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 0.0.1
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 0.0.1
195
+ - !ruby/object:Gem::Dependency
196
+ name: http
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '3.0'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '3.0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: deep_dup
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: 0.0.3
216
+ type: :runtime
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: 0.0.3
223
+ - !ruby/object:Gem::Dependency
224
+ name: deep_merge
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '1.2'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '1.2'
237
+ - !ruby/object:Gem::Dependency
238
+ name: diff-lcs
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: '1.3'
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: '1.3'
251
+ - !ruby/object:Gem::Dependency
252
+ name: docile
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - "~>"
256
+ - !ruby/object:Gem::Version
257
+ version: '1.3'
258
+ type: :runtime
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - "~>"
263
+ - !ruby/object:Gem::Version
264
+ version: '1.3'
265
+ - !ruby/object:Gem::Dependency
266
+ name: dry-struct
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - "~>"
270
+ - !ruby/object:Gem::Version
271
+ version: '0.4'
272
+ type: :runtime
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - "~>"
277
+ - !ruby/object:Gem::Version
278
+ version: '0.4'
279
+ - !ruby/object:Gem::Dependency
280
+ name: dry-validation
281
+ requirement: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - "~>"
284
+ - !ruby/object:Gem::Version
285
+ version: '0.11'
286
+ type: :runtime
287
+ prerelease: false
288
+ version_requirements: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - "~>"
291
+ - !ruby/object:Gem::Version
292
+ version: '0.11'
293
+ - !ruby/object:Gem::Dependency
294
+ name: ice_nine
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - "~>"
298
+ - !ruby/object:Gem::Version
299
+ version: 0.11.2
300
+ type: :runtime
301
+ prerelease: false
302
+ version_requirements: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - "~>"
305
+ - !ruby/object:Gem::Version
306
+ version: 0.11.2
307
+ - !ruby/object:Gem::Dependency
308
+ name: ougai
309
+ requirement: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - "~>"
312
+ - !ruby/object:Gem::Version
313
+ version: '1.5'
314
+ type: :runtime
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - "~>"
319
+ - !ruby/object:Gem::Version
320
+ version: '1.5'
321
+ - !ruby/object:Gem::Dependency
322
+ name: snake_camel
323
+ requirement: !ruby/object:Gem::Requirement
324
+ requirements:
325
+ - - "~>"
326
+ - !ruby/object:Gem::Version
327
+ version: '1.1'
328
+ type: :runtime
329
+ prerelease: false
330
+ version_requirements: !ruby/object:Gem::Requirement
331
+ requirements:
332
+ - - "~>"
333
+ - !ruby/object:Gem::Version
334
+ version: '1.1'
335
+ description:
336
+ email:
337
+ - ed@edropple.com
338
+ executables: []
339
+ extensions: []
340
+ extra_rdoc_files: []
341
+ files:
342
+ - ".editorconfig"
343
+ - ".gitignore"
344
+ - ".rspec"
345
+ - ".rubocop.yml"
346
+ - CODE_OF_CONDUCT.md
347
+ - Gemfile
348
+ - LICENSE.txt
349
+ - README.md
350
+ - Rakefile
351
+ - TODOS.md
352
+ - bin/console
353
+ - bin/setup
354
+ - example/Gemfile
355
+ - example/Gemfile.lock
356
+ - example/config.ru
357
+ - example/example.rb
358
+ - lib/modern.rb
359
+ - lib/modern/app.rb
360
+ - lib/modern/app/error_handling.rb
361
+ - lib/modern/app/request_handling.rb
362
+ - lib/modern/app/request_handling/input_handling.rb
363
+ - lib/modern/app/request_handling/output_handling.rb
364
+ - lib/modern/app/request_handling/request_container.rb
365
+ - lib/modern/app/router.rb
366
+ - lib/modern/app/trie_router.rb
367
+ - lib/modern/capsule.rb
368
+ - lib/modern/configuration.rb
369
+ - lib/modern/core_ext/array.rb
370
+ - lib/modern/core_ext/hash.rb
371
+ - lib/modern/descriptor.rb
372
+ - lib/modern/descriptor/content.rb
373
+ - lib/modern/descriptor/converters.rb
374
+ - lib/modern/descriptor/converters/input/base.rb
375
+ - lib/modern/descriptor/converters/input/json.rb
376
+ - lib/modern/descriptor/converters/output/base.rb
377
+ - lib/modern/descriptor/converters/output/json.rb
378
+ - lib/modern/descriptor/converters/output/yaml.rb
379
+ - lib/modern/descriptor/core.rb
380
+ - lib/modern/descriptor/info.rb
381
+ - lib/modern/descriptor/parameters.rb
382
+ - lib/modern/descriptor/request_body.rb
383
+ - lib/modern/descriptor/response.rb
384
+ - lib/modern/descriptor/route.rb
385
+ - lib/modern/descriptor/security.rb
386
+ - lib/modern/descriptor/server.rb
387
+ - lib/modern/doc_generator/open_api3.rb
388
+ - lib/modern/doc_generator/open_api3/operations.rb
389
+ - lib/modern/doc_generator/open_api3/paths.rb
390
+ - lib/modern/doc_generator/open_api3/schema_default_types.rb
391
+ - lib/modern/doc_generator/open_api3/schemas.rb
392
+ - lib/modern/doc_generator/open_api3/security_schemes.rb
393
+ - lib/modern/dsl.rb
394
+ - lib/modern/dsl/info.rb
395
+ - lib/modern/dsl/response_builder.rb
396
+ - lib/modern/dsl/root.rb
397
+ - lib/modern/dsl/route_builder.rb
398
+ - lib/modern/dsl/scope.rb
399
+ - lib/modern/dsl/scope_settings.rb
400
+ - lib/modern/errors.rb
401
+ - lib/modern/errors/error.rb
402
+ - lib/modern/errors/setup_errors.rb
403
+ - lib/modern/errors/web_errors.rb
404
+ - lib/modern/redirect.rb
405
+ - lib/modern/request.rb
406
+ - lib/modern/response.rb
407
+ - lib/modern/services.rb
408
+ - lib/modern/struct.rb
409
+ - lib/modern/types.rb
410
+ - lib/modern/util/header_parsing.rb
411
+ - lib/modern/util/trie_node.rb
412
+ - lib/modern/version.rb
413
+ - manual/01-why_modern.md
414
+ - modern.gemspec
415
+ homepage: https://github.com/modern-project/modern-ruby
416
+ licenses:
417
+ - MIT
418
+ metadata: {}
419
+ post_install_message:
420
+ rdoc_options: []
421
+ require_paths:
422
+ - lib
423
+ required_ruby_version: !ruby/object:Gem::Requirement
424
+ requirements:
425
+ - - "~>"
426
+ - !ruby/object:Gem::Version
427
+ version: '2.4'
428
+ required_rubygems_version: !ruby/object:Gem::Requirement
429
+ requirements:
430
+ - - ">="
431
+ - !ruby/object:Gem::Version
432
+ version: '0'
433
+ requirements: []
434
+ rubyforge_project:
435
+ rubygems_version: 2.7.3
436
+ signing_key:
437
+ specification_version: 4
438
+ summary: The OpenAPI-driven web framework for Ruby.
439
+ test_files: []