meta-api 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/lib/meta/application/execution.rb +19 -49
- data/lib/meta/application/metadata.rb +65 -5
- data/lib/meta/application/route.rb +4 -26
- data/lib/meta/config.rb +2 -2
- data/lib/meta/json_schema/builders/schema_builder_tool.rb +2 -1
- data/lib/meta/json_schema/schemas/array_schema.rb +13 -14
- data/lib/meta/json_schema/schemas/base_schema.rb +101 -36
- data/lib/meta/json_schema/schemas/object_schema.rb +22 -9
- data/lib/meta/json_schema/schemas/properties.rb +20 -74
- data/lib/meta/json_schema/schemas/scoping_schema.rb +41 -0
- data/lib/meta/json_schema/schemas/staging_schema.rb +58 -0
- data/lib/meta/json_schema/schemas/unsupported_schema.rb +22 -0
- data/lib/meta/json_schema/support/errors.rb +3 -0
- data/lib/meta/json_schema/support/schema_options.rb +0 -9
- data/lib/meta/route_dsl/meta_builder.rb +2 -2
- data/lib/meta/swagger_doc.rb +1 -1
- data/lib/meta/utils/kwargs/builder.rb +2 -0
- data/lib/meta/utils/route_dsl_builders.rb +1 -0
- data/meta-api.gemspec +6 -5
- metadata +71 -111
- data/.autoenv.zsh +0 -1
- data/.gitignore +0 -7
- data/.rubocop.yml +0 -28
- data/Gemfile +0 -19
- data/Gemfile.lock +0 -68
- data/README.md +0 -166
- data/Rakefile +0 -3
- data/docs/Rails.md +0 -61
- data/docs//345/220/215/347/247/260/347/224/261/346/235/245.md +0 -7
- data/docs//345/246/202/344/275/225/350/264/241/347/214/256.md +0 -10
- data/docs//346/225/231/347/250/213.md +0 -1708
- data/docs//347/264/242/345/274/225.md +0 -183
- data/examples/lobster.rb +0 -71
- data/examples/rack_app/README.md +0 -3
- data/examples/rack_app/config.ru +0 -6
- data/examples/rack_app/hello.rb +0 -6
- data/examples/rack_app/timing.rb +0 -15
- data/examples/rails_app/.gitattributes +0 -5
- data/examples/rails_app/.gitignore +0 -23
- data/examples/rails_app/.rspec +0 -1
- data/examples/rails_app/.ruby-version +0 -1
- data/examples/rails_app/Gemfile +0 -29
- data/examples/rails_app/Gemfile.lock +0 -190
- data/examples/rails_app/README.md +0 -11
- data/examples/rails_app/Rakefile +0 -6
- data/examples/rails_app/app/controllers/application_controller.rb +0 -7
- data/examples/rails_app/app/controllers/concerns/.keep +0 -0
- data/examples/rails_app/app/controllers/data_controller.rb +0 -63
- data/examples/rails_app/app/controllers/swagger_controller.rb +0 -13
- data/examples/rails_app/app/models/concerns/.keep +0 -0
- data/examples/rails_app/bin/rails +0 -4
- data/examples/rails_app/bin/rake +0 -4
- data/examples/rails_app/bin/setup +0 -25
- data/examples/rails_app/config/application.rb +0 -39
- data/examples/rails_app/config/boot.rb +0 -3
- data/examples/rails_app/config/credentials.yml.enc +0 -1
- data/examples/rails_app/config/environment.rb +0 -5
- data/examples/rails_app/config/environments/development.rb +0 -51
- data/examples/rails_app/config/environments/production.rb +0 -65
- data/examples/rails_app/config/environments/test.rb +0 -50
- data/examples/rails_app/config/initializers/cors.rb +0 -16
- data/examples/rails_app/config/initializers/filter_parameter_logging.rb +0 -8
- data/examples/rails_app/config/initializers/inflections.rb +0 -16
- data/examples/rails_app/config/initializers/meta_rails_plugin.rb +0 -3
- data/examples/rails_app/config/locales/en.yml +0 -33
- data/examples/rails_app/config/puma.rb +0 -43
- data/examples/rails_app/config/routes.rb +0 -13
- data/examples/rails_app/config.ru +0 -6
- data/examples/rails_app/lib/tasks/.keep +0 -0
- data/examples/rails_app/log/.keep +0 -0
- data/examples/rails_app/public/robots.txt +0 -1
- data/examples/rails_app/spec/data_controller_spec.rb +0 -60
- data/examples/rails_app/spec/rails_helper.rb +0 -55
- data/examples/rails_app/spec/spec_helper.rb +0 -94
- data/examples/rails_app/spec/swagger_controller_spec.rb +0 -13
- data/examples/rails_app/tmp/.keep +0 -0
- data/examples/rails_app/tmp/pids/.keep +0 -0
data/Gemfile.lock
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
meta-api (0.0.8)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://gems.ruby-china.com/
|
8
|
-
specs:
|
9
|
-
activesupport (7.0.1)
|
10
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
11
|
-
i18n (>= 1.6, < 2)
|
12
|
-
minitest (>= 5.1)
|
13
|
-
tzinfo (~> 2.0)
|
14
|
-
byebug (11.1.3)
|
15
|
-
coderay (1.1.3)
|
16
|
-
concurrent-ruby (1.1.9)
|
17
|
-
diff-lcs (1.5.0)
|
18
|
-
grape-entity (0.10.1)
|
19
|
-
activesupport (>= 3.0.0)
|
20
|
-
multi_json (>= 1.3.2)
|
21
|
-
hash_to_struct (1.0.0)
|
22
|
-
i18n (1.8.11)
|
23
|
-
concurrent-ruby (~> 1.0)
|
24
|
-
method_source (1.0.0)
|
25
|
-
minitest (5.15.0)
|
26
|
-
multi_json (1.15.0)
|
27
|
-
pry (0.13.1)
|
28
|
-
coderay (~> 1.1)
|
29
|
-
method_source (~> 1.0)
|
30
|
-
pry-byebug (3.9.0)
|
31
|
-
byebug (~> 11.0)
|
32
|
-
pry (~> 0.13.0)
|
33
|
-
rack (2.2.3)
|
34
|
-
rack-test (1.1.0)
|
35
|
-
rack (>= 1.0, < 3)
|
36
|
-
rake (12.3.3)
|
37
|
-
rspec (3.10.0)
|
38
|
-
rspec-core (~> 3.10.0)
|
39
|
-
rspec-expectations (~> 3.10.0)
|
40
|
-
rspec-mocks (~> 3.10.0)
|
41
|
-
rspec-core (3.10.1)
|
42
|
-
rspec-support (~> 3.10.0)
|
43
|
-
rspec-expectations (3.10.1)
|
44
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
45
|
-
rspec-support (~> 3.10.0)
|
46
|
-
rspec-mocks (3.10.2)
|
47
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
48
|
-
rspec-support (~> 3.10.0)
|
49
|
-
rspec-support (3.10.3)
|
50
|
-
tzinfo (2.0.4)
|
51
|
-
concurrent-ruby (~> 1.0)
|
52
|
-
|
53
|
-
PLATFORMS
|
54
|
-
ruby
|
55
|
-
|
56
|
-
DEPENDENCIES
|
57
|
-
grape-entity
|
58
|
-
hash_to_struct
|
59
|
-
i18n
|
60
|
-
meta-api!
|
61
|
-
pry-byebug
|
62
|
-
rack
|
63
|
-
rack-test
|
64
|
-
rake (~> 12.0)
|
65
|
-
rspec
|
66
|
-
|
67
|
-
BUNDLED WITH
|
68
|
-
2.3.7
|
data/README.md
DELETED
@@ -1,166 +0,0 @@
|
|
1
|
-
# Meta 框架
|
2
|
-
|
3
|
-
Meta 框架是一个用于开发 Web API 的后端框架,采用 Ruby 语言编写。正如它的名字,它是用定义“元”信息的方式实现 API,同时生成一份符合 Open API 规格的接口文档。
|
4
|
-
|
5
|
-
> 有关框架名称的由来,阅读[框架的名称由来](docs/名称由来.md)。
|
6
|
-
|
7
|
-
## 脚手架
|
8
|
-
|
9
|
-
可直接使用我的[脚手架](https://github.com/yetrun/web-frame-example)项目上手体验:
|
10
|
-
|
11
|
-
```bash
|
12
|
-
$ git clone https://github.com/yetrun/web-frame-example.git
|
13
|
-
```
|
14
|
-
|
15
|
-
## 安装
|
16
|
-
|
17
|
-
在 Gemfile 中添加:
|
18
|
-
|
19
|
-
```ruby
|
20
|
-
gem 'meta-api', '~> 0.0.8' # Meta 框架处于快速开发阶段,引入时应尽量固定版本
|
21
|
-
```
|
22
|
-
|
23
|
-
然后在 Ruby 代码中引用:
|
24
|
-
|
25
|
-
```ruby
|
26
|
-
require 'meta/api'
|
27
|
-
```
|
28
|
-
|
29
|
-
> 或者可嵌入到 Rails 项目中使用,参考[为 Rails 项目带来参数验证效果](docs/Rails.md)。
|
30
|
-
|
31
|
-
## 快速一览
|
32
|
-
|
33
|
-
### 定义 API
|
34
|
-
|
35
|
-
通过继承 `Meta::Application` 来定义一个 API 模块。(PS:以下示例的运行依赖 `ActiveRecord`)
|
36
|
-
|
37
|
-
```ruby
|
38
|
-
class NotesAPI < Meta::Application
|
39
|
-
get '/notes' do
|
40
|
-
title '查看笔记列表'
|
41
|
-
status 200 do
|
42
|
-
expose :notes, type: 'array', ref: NoteEntity
|
43
|
-
end
|
44
|
-
action do
|
45
|
-
render :notes, Note.all
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
post '/notes' do
|
50
|
-
title '创建新的笔记'
|
51
|
-
params do
|
52
|
-
param :note, type: 'object', ref: NoteEntity
|
53
|
-
end
|
54
|
-
status 201 do
|
55
|
-
expose :note, type: 'object', ref: NoteEntity.lock_scope('full')
|
56
|
-
end
|
57
|
-
action do
|
58
|
-
note = Note.create!(params[:note])
|
59
|
-
response.status = 201
|
60
|
-
render :note, note
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
get '/notes/:id' do
|
65
|
-
title '查看笔记'
|
66
|
-
params do
|
67
|
-
param :id, type: 'integer'
|
68
|
-
end
|
69
|
-
status 200 do
|
70
|
-
expose :note, type: 'object', ref: NoteEntity.lock_scope('full')
|
71
|
-
end
|
72
|
-
action do
|
73
|
-
note = Note.find(params[:id])
|
74
|
-
render :note, note, scope: 'full'
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
put '/notes/:id' do
|
79
|
-
title '更新笔记'
|
80
|
-
params do
|
81
|
-
param :note, type: 'object', ref: NoteEntity
|
82
|
-
end
|
83
|
-
status 200 do
|
84
|
-
expose :note, type: 'object', ref: NoteEntity.lock_scope('full')
|
85
|
-
end
|
86
|
-
action do
|
87
|
-
note = Note.find(params[:id])
|
88
|
-
note.update!(params[:note])
|
89
|
-
render :note, note, scope: 'full'
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
delete '/notes/:id' do
|
94
|
-
title '删除笔记'
|
95
|
-
status 204
|
96
|
-
action do
|
97
|
-
note = Note.find(params[:id])
|
98
|
-
note.destroy!
|
99
|
-
response.status = 204
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
```
|
104
|
-
|
105
|
-
### 定义实体
|
106
|
-
|
107
|
-
以上示例看到有用到 `NoteEntity`,它是一个预先定义的实体:
|
108
|
-
|
109
|
-
```ruby
|
110
|
-
class NoteEntity < Meta::Entity
|
111
|
-
property :id, type: 'integer', param: false # 不作为参数传递
|
112
|
-
property :title, type: 'string'
|
113
|
-
property :content, type: 'string', render: { scope: 'full' } # 列表页接口不返回此字段
|
114
|
-
end
|
115
|
-
```
|
116
|
-
|
117
|
-
### 生成 API 文档
|
118
|
-
|
119
|
-
通过主动调用以下的方法可以生成 Open API 的规格文档:
|
120
|
-
|
121
|
-
```ruby
|
122
|
-
NotesAPI.to_swagger_doc
|
123
|
-
```
|
124
|
-
|
125
|
-
该 Open API 文档是 JSON 格式,可以在 Swagger UI 下预览效果。如果也不乐意自己搭建 Swagger UI,可以直接使用在线的:
|
126
|
-
|
127
|
-
> http://openapi.yet.run/playground
|
128
|
-
|
129
|
-
### 将模块挂载在 Rack 下运行
|
130
|
-
|
131
|
-
API 模块同时也是一个 Rack 中间件,它可以挂载在 Rack 下运行。假设以上文件分别位于 `notes_api.rb` 和 `note_entity.rb`,在项目下新建文件 `config.ru`,并写入:
|
132
|
-
|
133
|
-
```ruby
|
134
|
-
require 'meta/api'
|
135
|
-
require_relative 'notes_api'
|
136
|
-
require_relative 'note_entity'
|
137
|
-
|
138
|
-
# 将文档挂载到 /api_spec 锚点下
|
139
|
-
map '/api_spec' do
|
140
|
-
run ->(env) {
|
141
|
-
[200, { 'CONTENT_TYPE' => 'application/json' }, [JSON.generate(NotesAPI.to_swagger_doc)]]
|
142
|
-
}
|
143
|
-
end
|
144
|
-
|
145
|
-
# 启动 NotesAPI 中定义的接口
|
146
|
-
run NotesAPI
|
147
|
-
```
|
148
|
-
|
149
|
-
然后执行命令:`bundle exec rackup`,接口即可启动。
|
150
|
-
|
151
|
-
## 文档
|
152
|
-
|
153
|
-
- [教程](docs/教程.md)
|
154
|
-
- [索引](docs/索引.md)
|
155
|
-
|
156
|
-
## 支持
|
157
|
-
|
158
|
-
你可以通过以下途径获得支持:
|
159
|
-
|
160
|
-
1. 通过 GitHub 提交 [ISSUE](https://github.com/yetrun/web-frame/issues)
|
161
|
-
2. 通过 QQ 群(489579810)获得实时答疑
|
162
|
-
3. 对本项目提交 [Pull Request](https://github.com/yetrun/web-frame/pulls)
|
163
|
-
|
164
|
-
## License
|
165
|
-
|
166
|
-
LGPL-2.1
|
data/Rakefile
DELETED
data/docs/Rails.md
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# 作为 Rails 插件
|
2
|
-
|
3
|
-
## 安装
|
4
|
-
|
5
|
-
首先,你需要将其安装在 Rails 项目中:
|
6
|
-
|
7
|
-
```ruby
|
8
|
-
gem 'meta-api', '~> 0.0.3' # 0.0.3 版本以上才提供 Rails 插件功能
|
9
|
-
```
|
10
|
-
|
11
|
-
在 config/initializers 目录下创建一个文件,例如 `meta_rails_plugin.rb`,并写入:
|
12
|
-
|
13
|
-
```ruby
|
14
|
-
require 'meta/rails'
|
15
|
-
|
16
|
-
Meta::Rails.setup
|
17
|
-
```
|
18
|
-
|
19
|
-
在 `application_controller.rb` 下加入:
|
20
|
-
|
21
|
-
```ruby
|
22
|
-
class ApplicationController < ActionController::API
|
23
|
-
# 引入插件,同时引入 route 宏、params_on_schema 方法、json_on_schema 渲染器
|
24
|
-
include Meta::Rails::Plugin
|
25
|
-
|
26
|
-
# 处理参数验证错误
|
27
|
-
rescue_from Meta::Errors::ParameterInvalid do |e|
|
28
|
-
render json: e.errors, status: :bad_request
|
29
|
-
end
|
30
|
-
end
|
31
|
-
```
|
32
|
-
|
33
|
-
这样,一切就准备好了。
|
34
|
-
|
35
|
-
## 示例
|
36
|
-
|
37
|
-
接口定义:
|
38
|
-
|
39
|
-
```ruby
|
40
|
-
class UsersController < ApplicationController
|
41
|
-
route '/users', :post do
|
42
|
-
params do
|
43
|
-
param :user, required: true do
|
44
|
-
param :name, type: 'string'
|
45
|
-
param :age, type: 'integer'
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
def create
|
50
|
-
user = User.create!(params_on_schema[:user])
|
51
|
-
render json_on_schema: user
|
52
|
-
end
|
53
|
-
end
|
54
|
-
```
|
55
|
-
|
56
|
-
生成 Swagger 文档:
|
57
|
-
|
58
|
-
```ruby
|
59
|
-
Rails.application.eager_load! # 需要提前加载所有常量
|
60
|
-
Meta::Rails::Plugin.generate_swagger_doc(ApplicationController)
|
61
|
-
```
|
@@ -1,7 +0,0 @@
|
|
1
|
-
# 框架的名称由来
|
2
|
-
|
3
|
-
我一直在寻找适合在团队内使用的纯 API 框架。我先是试用了 Rails API 模式,继而又尝试了 Grape 框架。面对这种框架我始终觉得缺少了些什么。这种缺憾似乎是与 API 文档相关的。我似乎每次都要先实现一遍业务逻辑,然后再想办法编写一个文档(或者反过来)。在文档和业务逻辑结合方面,Rails 做得不够好,Grape 做得更好一些,但还是不够好。
|
4
|
-
|
5
|
-
直到后来,我尝试自己编写 API 框架时,一个词汇在脑海里涌现。Meta,即“元”,当我们撰写 API 文档时,实际上就是在定义 API 文档的元信息。然后,我就尝试将脑海中的想法付诸实践。编写 API,我们首先是编写 API 的元信息;然后对应地,API 的相关实现就已经有了,诸如参数的解析、实体的渲染等;然后对应地,一份 API 文档也就生成了。我们不用为了生成一份文档再单独地另写一套逻辑,我们只用定义一遍它的元信息。
|
6
|
-
|
7
|
-
这就是 Meta 框架名称的由来。
|