2. Obligatory "Who am I" slide
● Sean Kelly (Hi!)
○ But everyone calls me Stabby
● I work for Tapjoy
○ We serve hundreds of millions of ads a day on a global scale
● I have a new puppy and a new kitty
○ Some of these slides might accidentally veer into tips on Crate Training
● I maintain a bunch of open source libraries
○ That literally nobody uses
○ It's actually kind of fun, since I can break things with less repurcussions
3. What am I here to talk about?
● Service Oriented Architecture
● Defining Dependencies
● Separation of Concerns
● Practical example of applying the above in a Go webservice
5. Service Oriented Architecture
● Many ways to define and apply this
● Internally architecting your application for SOA is a great pattern for maintaining
application code
● Keep crucial business logic out of Models and Controllers
○ Helpers like combining First + Last into FullName can live on a Model
○ Try to avoid ivory-towering yourself into code no one wants to maintain
● Centralize it in reusable Service objects
● These objects define domain boundaries in your systems
● These objects also define dependency maps between the parts of your systems
● Eventually, if you do break your app up into microservices, internal SOA has
already got your code in a "ready to extract" state
6. Dependencies
Ugh, is he gonna tell us to use some interface{} abusing DI
framework?
(Spoiler Alert: Nah)
7. Dependencies
● External resources you rely upon to execute code
● Common examples:
○ MySQL
○ Memcached
○ Riak
● Less Common examples:
○ Configuration data
○ Other code modules
● "Hmm, I need access to X here…"
○ That is probably a dependency
● Passing dependencies down via a constructor makes for more testable, reliable
code.
● Avoid "new-ing up" a dependency unless it's in your main() and handed to others
9. Separation of Concerns
● Modules of code should have 1 purpose
● Don't lump things together out of convenience
● Each distinct piece of your domain should get it's own Service object
● You can compose Service objects to create "Higher Order" Services
○ If Service A needs Service B, but Service B needs Service A…
○ You need Service C, composed of A and B
● So, if you had some basic Services like these:
○ UserService
○ ErrorService
○ ThirdPartyMailerService
● You might compose some Services like these:
○ AccountManagementService(UserService, ThirdPartyMailerService)
○ AlertingService(AccountService, ErrorService, ThirdPartyMailerService)
11. Testing
● Service Objects with their dependencies declared in their New method: 80% of
the way there
● The other 20%: Interfaces!
● If instead of this…
○ NewAlertingService(*AccountService, *ErrorService, *SomeEmailProvider) *AlertingService
● You did this…
○ NewAlertingService(IAccountService, IErrorService, IEmailService) IAlerteringService
● You could replace any of the critical dependencies in a unit test with mocks or no-
op implementations
● You can now use tools like `gomock` to generate test implementations for you
○ Or, just do it yourself if your services are small / have specialized testing needs
● Conversely, you could mock out the dependencies of those Services
○ But usually, whole-mocking is easier and more straightforward
13. Services, Dependencies, and You
● Primary focus is to keep code "clean" and DRY
● Each service does one thing, and does it well
● They define dependencies in the constructor / New method
● Create "Higher Order" Services by combining existing Services
● More easily testable with both unit and integration tests
○ Especially if you use Interfaces
● Lays the groundwork for extraction into microservices, should you choose to
○ If the code is cleanly separated, and has well defined dependencies, it's more straightforward to port
● And Now… Sample code!