Skip to content

Instantly share code, notes, and snippets.

@AfolabiOlaoluwa
Created July 29, 2019 13:19
Show Gist options
  • Save AfolabiOlaoluwa/81d1419d39a1348c966d61922fde1636 to your computer and use it in GitHub Desktop.
Save AfolabiOlaoluwa/81d1419d39a1348c966d61922fde1636 to your computer and use it in GitHub Desktop.
When Should I Not Use a Service Object?
## When Should I Not Use a Service Object?
This one’s easy. I have these rules:
1. Does your code handle routing, params or do other controller-y things?
If so, don’t use a service object—your code belongs in the controller.
2. Are you trying to share your code in different controllers?
In this case, don’t use a service object—use a concern.
3. Is your code like a model that doesn’t need persistence?
If so, don’t use a service object. Use a non-ActiveRecord model instead.
4. Is your code a specific business action? (e.g., “Take out the trash,” “Generate a PDF using this text,” or “Calculate the customs duty using these complicated rules”)
In this case, use a service object. That code probably doesn’t logically fit in either your controller or your model.
Of course, these are my rules, so you’re welcome to adapt them to your own use cases. These have worked very well for me, but your mileage may vary.
## Rules for Writing Good Service Objects
I have a four rules for creating service objects. These aren’t written in stone, and if you really want to break them, you can, but I will probably ask you to change it in code reviews unless your reasoning is sound.
Rule 1: Only One Public Method per Service Object
Service objects are single business actions. You can change the name of your public method if you like. I prefer using call, but Gitlab CE’s codebase calls it execute and other people may use perform. Use whatever you want—you could call it nermin for all I care. Just don’t create two public methods for a single service object. Break it into two objects if you need to.
Rule 2: Name Service Objects Like Dumb Roles at a Company
Service objects are single business actions. Imagine if you hired one person at the company to do that one job, what would you call them? If their job is to create tweets, call them TweetCreator. If their job is to read specific tweets, call them TweetReader.
Rule 3: Don’t Create Generic Objects to Perform Multiple Actions
Service objects are single business actions. I broke the functionality into two pieces: TweetReader, and ProfileFollower. What I didn’t do is create a single generic object called TwitterHandler and dump all of the API functionality in there. Please don’t do this. This goes against the “business action” mindset and makes the service object look like the Twitter Fairy. If you want to share code among the business objects, just create a BaseTwitterManager object or module and mix that into your service objects.
Rule 4: Handle Exceptions Inside the Service Object
For the umpteenth time: Service objects are single business actions. I can’t say this enough. If you’ve got a person that reads tweets, they’ll either give you the tweet, or say, “This tweet doesn’t exist.” Similarly, don’t let your service object panic, jump on your controller’s desk, and tell it to halt all work because “Error!” Just return false and let the controller move on from there.
@AfolabiOlaoluwa
Copy link
Author

I copied this out from https://www.toptal.com/ruby-on-rails/rails-service-objects-tutorial because it resonates well with my views and I like to always keep track of it. I have seen so many abuse of Service Object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment