rails_api_base 1.0.5
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/MIT-LICENSE +20 -0
- data/README.md +19 -0
- data/Rakefile +6 -0
- data/app/assets/stylesheets/rails_api_base/application.css +15 -0
- data/app/controllers/concerns/blueprint_options_support.rb +55 -0
- data/app/controllers/rails_api_base/application_controller.rb +4 -0
- data/app/controllers/rails_api_base/base_controller.rb +111 -0
- data/app/helpers/rails_api_base/application_helper.rb +4 -0
- data/app/jobs/rails_api_base/application_job.rb +4 -0
- data/app/mailers/rails_api_base/application_mailer.rb +6 -0
- data/app/models/rails_api_base/application_record.rb +5 -0
- data/app/views/layouts/rails_api_base/application.html.erb +17 -0
- data/config/routes.rb +2 -0
- data/lib/rails_api_base/engine.rb +5 -0
- data/lib/rails_api_base/version.rb +3 -0
- data/lib/rails_api_base.rb +10 -0
- data/lib/tasks/rails_api_base_tasks.rake +4 -0
- metadata +103 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: fb904521fc43085746d44855945b2705573c9957abceef8691e2d8efd02a8cba
|
|
4
|
+
data.tar.gz: 8a5baa7e4fba53842e804cdb4e92763a372693ac254e0d7cdfba9f54637125f0
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 6fa8391f02e591ca8f378a116d2380304a54f76520044018d076aeac9c1a2e6be7c17a3d262178a17fa89f4c6246d72e519bb467ddd1b3dca52fb196f6ffa998
|
|
7
|
+
data.tar.gz: c5caf86b40ef20edd0c33c5df1371a11a9382a2e6cd2addfcb4670e6659880922bdff44ed6e0d65dc5f4c6c76721d21197933b826b2017324f3333f65a8b6c4e
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright aric.zheng
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# rails_api_base
|
|
2
|
+
> Standardized JSON API base controller for Rails with Blueprinter support.
|
|
3
|
+
|
|
4
|
+
## Features
|
|
5
|
+
|
|
6
|
+
- Unified response format: `{ code, msg, data }`
|
|
7
|
+
- Field selection via `?fields=title,user`
|
|
8
|
+
- Auto Blueprinter integration (`PostBlueprint`)
|
|
9
|
+
- CRUD scaffolding (index/show/create/update/destroy)
|
|
10
|
+
- Customizable response codes
|
|
11
|
+
- N+1 safe (with proper `includes` in controller)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Add to your Gemfile:
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
gem 'rails_api_base'
|
|
19
|
+
gem 'blueprinter'
|
data/Rakefile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
|
11
|
+
* It is generally better to create a new file per style scope.
|
|
12
|
+
*
|
|
13
|
+
*= require_tree .
|
|
14
|
+
*= require_self
|
|
15
|
+
*/
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# app/controllers/concerns/blueprint_options_support.rb
|
|
2
|
+
module BlueprintOptionsSupport
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
# 声明 DSL
|
|
7
|
+
class << self
|
|
8
|
+
def blueprint_options_default(*modes)
|
|
9
|
+
@blueprint_modes = modes
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def blueprint_modes
|
|
13
|
+
# 支持继承:如果子类没定义,就继承父类的设置
|
|
14
|
+
if instance_variable_defined?(:@blueprint_modes)
|
|
15
|
+
@blueprint_modes
|
|
16
|
+
else
|
|
17
|
+
superclass.respond_to?(:blueprint_modes) ? superclass.blueprint_modes : []
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# === 主入口 ===
|
|
24
|
+
def blueprint_options
|
|
25
|
+
opts = {}
|
|
26
|
+
self.class.blueprint_modes.each do |mode|
|
|
27
|
+
method_name = "blueprint_options_for_#{mode}"
|
|
28
|
+
if respond_to?(method_name, true)
|
|
29
|
+
opts.merge!(send(method_name))
|
|
30
|
+
else
|
|
31
|
+
Rails.logger.warn("[BlueprintOptionsSupport] Unknown mode: #{mode}")
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
opts
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
# === 模式定义区 ===
|
|
40
|
+
def blueprint_options_for_defaults
|
|
41
|
+
{ params: params }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def blueprint_options_for_fields
|
|
45
|
+
return {} unless params[:fields].present?
|
|
46
|
+
|
|
47
|
+
fields = params[:fields].split(",").map(&:strip).map(&:to_sym)
|
|
48
|
+
{ fields: fields }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# 你未来还可以轻松扩展:
|
|
52
|
+
# def blueprint_options_for_locale
|
|
53
|
+
# { locale: I18n.locale }
|
|
54
|
+
# end
|
|
55
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# app/controllers/rails_api_base/base_controller.rb
|
|
2
|
+
module RailsApiBase
|
|
3
|
+
class BaseController < ActionController::API
|
|
4
|
+
include BlueprintOptionsSupport
|
|
5
|
+
|
|
6
|
+
# 默认开启 :defaults 模式
|
|
7
|
+
blueprint_options_default :defaults
|
|
8
|
+
|
|
9
|
+
# === 统一成功响应 ===
|
|
10
|
+
def render_success(data, status: :ok, message: "success", code: nil)
|
|
11
|
+
code ||= response_code_for(action_name, status: status)
|
|
12
|
+
render json: { code: code, msg: message, data: data }, status: status
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# === 统一错误响应 ===
|
|
16
|
+
def render_error(message: "Unprocessable Entity", status: :unprocessable_entity, errors: nil)
|
|
17
|
+
code = response_code_for(action_name, status: status)
|
|
18
|
+
render json: { code: code, msg: message, errors: errors }, status: status
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# === 允许子类自定义响应 code ===
|
|
22
|
+
def response_code_for(action, **context)
|
|
23
|
+
status = context[:status] || :ok
|
|
24
|
+
if status.is_a?(Integer)
|
|
25
|
+
status
|
|
26
|
+
else
|
|
27
|
+
Rack::Utils::SYMBOL_TO_STATUS_CODE.fetch(status, 200)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# === CRUD 基础动作 ===
|
|
32
|
+
before_action :set_resource, only: %i[show update destroy]
|
|
33
|
+
|
|
34
|
+
def index
|
|
35
|
+
items = collection
|
|
36
|
+
data = serialize_collection(items)
|
|
37
|
+
render_success(data)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def show
|
|
41
|
+
data = serialize_resource(resource)
|
|
42
|
+
render_success(data)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def create
|
|
46
|
+
resource = resource_class.new(resource_params)
|
|
47
|
+
if resource.save
|
|
48
|
+
data = serialize_resource(resource)
|
|
49
|
+
render_success(data, status: :created, message: "Created successfully")
|
|
50
|
+
else
|
|
51
|
+
render_error(message: "Validation failed", errors: resource.errors.full_messages)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def update
|
|
56
|
+
if resource.update(resource_params)
|
|
57
|
+
data = serialize_resource(resource)
|
|
58
|
+
render_success(data, message: "Updated successfully")
|
|
59
|
+
else
|
|
60
|
+
render_error(message: "Validation failed", errors: resource.errors.full_messages)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def destroy
|
|
65
|
+
resource.destroy
|
|
66
|
+
render_success(nil, message: "Deleted successfully")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
# === 序列化逻辑 ===
|
|
72
|
+
def serialize_resource(resource)
|
|
73
|
+
bp = blueprint_class
|
|
74
|
+
bp ? bp.render_as_hash(resource, **blueprint_options) : resource.as_json
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def serialize_collection(collection)
|
|
78
|
+
bp = blueprint_class
|
|
79
|
+
bp ? bp.render_as_hash(collection, **blueprint_options) : collection.as_json
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def blueprint_class
|
|
83
|
+
"#{resource_class}Blueprint".constantize
|
|
84
|
+
rescue NameError
|
|
85
|
+
nil
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# === 资源推导 ===
|
|
89
|
+
def resource_class
|
|
90
|
+
controller_name.singularize.classify.constantize
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def resource
|
|
94
|
+
instance_variable_get("@#{controller_name.singularize}")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def set_resource
|
|
98
|
+
instance_variable_set("@#{controller_name.singularize}", resource_class.find(params[:id]))
|
|
99
|
+
rescue ActiveRecord::RecordNotFound
|
|
100
|
+
render_error(message: "Record not found", status: :not_found)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def collection
|
|
104
|
+
resource_class.all
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def resource_params
|
|
108
|
+
raise NotImplementedError, "Subclass must implement ##{controller_name.singularize}_params"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Rails api base</title>
|
|
5
|
+
<%= csrf_meta_tags %>
|
|
6
|
+
<%= csp_meta_tag %>
|
|
7
|
+
|
|
8
|
+
<%= yield :head %>
|
|
9
|
+
|
|
10
|
+
<%= stylesheet_link_tag "rails_api_base/application", media: "all" %>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
|
|
14
|
+
<%= yield %>
|
|
15
|
+
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
data/config/routes.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rails_api_base
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.5
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- aric.zheng
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2025-11-06 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rails
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '6.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '6.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: blueprinter
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: kaminari
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
description: Standardized JSON API foundation for Rails apps.
|
|
55
|
+
email:
|
|
56
|
+
- 1290657123@qq.com
|
|
57
|
+
executables: []
|
|
58
|
+
extensions: []
|
|
59
|
+
extra_rdoc_files: []
|
|
60
|
+
files:
|
|
61
|
+
- MIT-LICENSE
|
|
62
|
+
- README.md
|
|
63
|
+
- Rakefile
|
|
64
|
+
- app/assets/stylesheets/rails_api_base/application.css
|
|
65
|
+
- app/controllers/concerns/blueprint_options_support.rb
|
|
66
|
+
- app/controllers/rails_api_base/application_controller.rb
|
|
67
|
+
- app/controllers/rails_api_base/base_controller.rb
|
|
68
|
+
- app/helpers/rails_api_base/application_helper.rb
|
|
69
|
+
- app/jobs/rails_api_base/application_job.rb
|
|
70
|
+
- app/mailers/rails_api_base/application_mailer.rb
|
|
71
|
+
- app/models/rails_api_base/application_record.rb
|
|
72
|
+
- app/views/layouts/rails_api_base/application.html.erb
|
|
73
|
+
- config/routes.rb
|
|
74
|
+
- lib/rails_api_base.rb
|
|
75
|
+
- lib/rails_api_base/engine.rb
|
|
76
|
+
- lib/rails_api_base/version.rb
|
|
77
|
+
- lib/tasks/rails_api_base_tasks.rake
|
|
78
|
+
homepage: https://js.work
|
|
79
|
+
licenses:
|
|
80
|
+
- MIT
|
|
81
|
+
metadata:
|
|
82
|
+
allowed_push_host: https://rubygems.org
|
|
83
|
+
homepage_uri: https://js.work
|
|
84
|
+
source_code_uri: https://github.com/afeiship/rails_api_base
|
|
85
|
+
changelog_uri: https://github.com/afeiship/rails_api_base/blob/master/CHANGELOG.md
|
|
86
|
+
rdoc_options: []
|
|
87
|
+
require_paths:
|
|
88
|
+
- lib
|
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - ">="
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
|
+
requirements:
|
|
96
|
+
- - ">="
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '0'
|
|
99
|
+
requirements: []
|
|
100
|
+
rubygems_version: 3.6.3
|
|
101
|
+
specification_version: 4
|
|
102
|
+
summary: Standardized JSON API foundation for Rails apps.
|
|
103
|
+
test_files: []
|