Grape API:以编程方式创建端点
Grape API: Create endpoint programmatically
我有非常基本的 CRUD 端点,这些端点在我的资源中反复出现。
目前我有一个 Rails 生成器可以帮助我更快地生成 API 端点。
明显的缺点是,每当我对模板进行更改时,我都需要更新一堆文件。
由于我的一些端点有一个非常清晰的模式,我想知道是否有办法动态生成它们。
类似于调用调用 desc、params 等的方法...:[=12=]
def delete(target)
klass = target.camelize.constantize
entity = V1::Entities.const_defined?(target.camelize) ? V1::Entities.get_const(target.camelize) : nil
desc "Delete a #{target}", {
http_codes: [
{ code: 204, message: "#{target} deleted successfully", model: entity},
{ code: 401, message: 'Unauthorized', model: Entities::ApiError },
{ code: 403, message: 'Forbidden', model: Entities::ApiError },
{ code: 404, message: 'Not Found', model: Entities::ApiError },
]
}
params do
requires :id, type: Integer, documentation: entity.documentation[:id]
end
route_param :id do
delete do
resource = klass.find_by(id: params[:id])
must_have_record!(resource)
authenticate! and authorize!("#{target.upcase}_DELETE".to_sym, resource)
if resource.destroy
present resource, with: entity
else
destroy_error!
end
end
end
end
我知道上面的方法行不通也没有意义。这只是一个例子来说明我的想法。
我能够通过将以下静态方法添加到我的 Base < Grape:API 以编程方式创建端点。重要的是不要调用已经存在的 Grape::API class 的静态方法(例如 get、post、delete、patch、put、...):
#######################################################################################
### AUTOMAGICALLY GENERATES AN API TO DESTROY A RESOURCE
#######################################################################################
def self.destroy(model)
model_entity = model.const_defined?("Entity") ? model::Entity : nil
resource model.to_s.underscore.pluralize do
desc "Delete a #{model.to_s.downcase}", {
http_codes: [
{ code: 204, message: "#{model.to_s.downcase} deleted successfully", model: model_entity },
{ code: 401, message: "Unauthorized", model: Entities::ApiError },
{ code: 403, message: "Forbidden", model: Entities::ApiError },
{ code: 404, message: "Not Found", model: Entities::ApiError },
]
}
params do
requires :id, type: Integer, documentation: model_entity && model_entity.documentation[:id] ? model_entity.documentation[:id] : { type: "Integer", desc: "" }
end
route_param :id do
delete do
resource = model.find_by(id: params[:id])
must_have_record!(resource)
authenticate! and authorize!(:"#{model.to_s.upcase}_DELETE", resource)
if resource.destroy
present resource, with: model_entity
else
destroy_error!
end
end
end
end
end
我有非常基本的 CRUD 端点,这些端点在我的资源中反复出现。
目前我有一个 Rails 生成器可以帮助我更快地生成 API 端点。
明显的缺点是,每当我对模板进行更改时,我都需要更新一堆文件。
由于我的一些端点有一个非常清晰的模式,我想知道是否有办法动态生成它们。
类似于调用调用 desc、params 等的方法...:[=12=]
def delete(target)
klass = target.camelize.constantize
entity = V1::Entities.const_defined?(target.camelize) ? V1::Entities.get_const(target.camelize) : nil
desc "Delete a #{target}", {
http_codes: [
{ code: 204, message: "#{target} deleted successfully", model: entity},
{ code: 401, message: 'Unauthorized', model: Entities::ApiError },
{ code: 403, message: 'Forbidden', model: Entities::ApiError },
{ code: 404, message: 'Not Found', model: Entities::ApiError },
]
}
params do
requires :id, type: Integer, documentation: entity.documentation[:id]
end
route_param :id do
delete do
resource = klass.find_by(id: params[:id])
must_have_record!(resource)
authenticate! and authorize!("#{target.upcase}_DELETE".to_sym, resource)
if resource.destroy
present resource, with: entity
else
destroy_error!
end
end
end
end
我知道上面的方法行不通也没有意义。这只是一个例子来说明我的想法。
我能够通过将以下静态方法添加到我的 Base < Grape:API 以编程方式创建端点。重要的是不要调用已经存在的 Grape::API class 的静态方法(例如 get、post、delete、patch、put、...):
#######################################################################################
### AUTOMAGICALLY GENERATES AN API TO DESTROY A RESOURCE
#######################################################################################
def self.destroy(model)
model_entity = model.const_defined?("Entity") ? model::Entity : nil
resource model.to_s.underscore.pluralize do
desc "Delete a #{model.to_s.downcase}", {
http_codes: [
{ code: 204, message: "#{model.to_s.downcase} deleted successfully", model: model_entity },
{ code: 401, message: "Unauthorized", model: Entities::ApiError },
{ code: 403, message: "Forbidden", model: Entities::ApiError },
{ code: 404, message: "Not Found", model: Entities::ApiError },
]
}
params do
requires :id, type: Integer, documentation: model_entity && model_entity.documentation[:id] ? model_entity.documentation[:id] : { type: "Integer", desc: "" }
end
route_param :id do
delete do
resource = model.find_by(id: params[:id])
must_have_record!(resource)
authenticate! and authorize!(:"#{model.to_s.upcase}_DELETE", resource)
if resource.destroy
present resource, with: model_entity
else
destroy_error!
end
end
end
end
end