- Microservices Development Cookbook
- Paul Osman
- 472字
- 2021-07-16 17:48:27
How to do it...
Refactoring any code base is a process. For monoliths, there are a few techniques that can work quite well. In this example, we'll document the steps that can be taken to make refactoring a Ruby on Rails code base easy:
- Using the techniques described in previous recipes, identify business capabilities and bounded contexts within your application. Let's focus on the ability to upload pictures and videos.
- Create a directory called app/services alongside controllers, models, and views. This directory will hold all of your service objects. Service objects are a pattern used in many Rails applications to factor out a conceptual service into a ruby object that does not inherit any Ruby on Rails functionality. This will make it easier to move the functionality encapsulated within a service object into a separate microservice. There is no one way to structure your service objects. I prefer to have each object represent a service, and move operations I want that service to be responsible for to that service object as methods.
- Create a new file called attachments_service.rb under app/services and give it the following definition:
class AttachmentsService
def upload
# ...
end
def delete!
# ...
end
end
- Looking at the source code for the AttachmentsController#create method in the app/controllers/attachments_controller.rb file, it currently handles the responsibility for creating the Attachment instance and uploading the file data to the attachment store, which in this case is an Amazon S3 bucket. This is the functionality that we need to move to the newly created service object:
# POST /messages/:message_id/attachments
def create
message = Message.find_by!(params[:message_id], user_id:
current_user.id)
file = StorageBucket.files.create(
key: params[:file][:name],
body: StringIO.new(Base64.decode64(params[:file][:data]),
'rb'),
public: true
)
attachment = Attachment.new(attachment_params.merge!(message:
message))
attachment.url = file.public_url
attachment.file_name = params[:file][:name]
attachment.save
json_response({ url: attachment.url }, :created)
end
- Open the newly created service object in the app/services/attachments_service.rb file and move the responsibility for uploading the file to the AttachmentsService#upload method:
class AttachmentsService
def upload(message_id, user_id, file_name, data, media_type)
message = Message.find_by!(message_id, user_id: user_id)
file = StorageBucket.files.create(
key: file_name,
body: StringIO.new(Base64.decode64(data), 'rb'),
public: true
)
Attachment.create(
media_type: media_type,
file_name: file_name,
url: file.public_url,
message: message
)
end
def delete!
end
end
- Now upload the AttachmentsController#create method in app/controllers/attachments_controller.rb to use the newly created AttachmentsService#upload method:
# POST /messages/:message_id/attachments
def create
service = AttachmentService.new
attachment = service.upload(params[:message_id], current_user.id,
params[:file][:name], params[:file][:data],
params[:media_type])
json_response({ url: attachment.url }, :created)
end
- Repeat this process for code in the AttachmentsController#destroy method, moving the responsibility to the new service object. When you're finished, no code in AttachmentsController should be interacting with the Attachments model directly; instead, it should be going through the AttachmentsService service object.
You've now isolated responsibility for the management of attachments to a single service class. This class should encapsulate all of the business logic that will eventually be moved to a new attachment service.
推薦閱讀
- 連接未來:從古登堡到谷歌的網絡革命
- C++黑客編程揭秘與防范
- 物聯網安全:理論、實踐與創新
- 5G承載網網絡規劃與組網設計
- Hands-On Chatbot Development with Alexa Skills and Amazon Lex
- HCNA網絡技術
- 互聯網安全的40個智慧洞見:2015年中國互聯網安全大會文集
- Practical Web Design
- Yii Application Development Cookbook(Second Edition)
- Working with Legacy Systems
- Learning Storm
- 人人都該都懂的互聯網思維
- 大型企業微服務架構實踐與運營
- 黑客心理學:社會工程學原理
- 物聯網商業設計與案例