Developer Notes : Service Oriented Architecture and Rails
Why do we need to do up-front design of services?
Service oriented systems sacrifice iteration speed for stability, reuse and robustness.
What is robustness?
Ability to withstand changes in the operating environment without loss of functionality. Example: code changes, moving to another database etc.
When is services a good choice?
When an application has a stable, well-defined, and well-understood requirements.
What are the advantages of using services rather than a monolithic application?
What are the benefits of isolation?
- Easier to manage and optimize.
- Can be tested separately from other parts of an application.
- Easy way of organizing larger teams.
What are the different levels of isolation?
Business logic, shared system and full isolation.
What is business logic isolation?
Services that isolate based on business logic generally have their own application code, with a shared data store and shared systems.
What is shared system isolation?
Services running inside their own application instances. Each has its own databases but they could be running on the same hardware.
What is full isolation?
Services have their own server instances, separate code bases and their own data stores.
How does services approach help with scalability?
Using services makes it easy to scale portions of an application individually. Data can be split across services, and the performance under load can be optimized for each service. Once service can optimize for data writes, another for reads.
How does services approach provide agility?
Switching infrastructure choices and upgrading libraries is easier.
How do you deal with versioning?
Each service interface should be versioned when an update includes a breaking change. We must be able to run multiple versions of a service simultaneously. If an update is additive, the service can remain at the same version.
Converting to Services
Segmenting into Services
Questions to determine how to redesign for services:
- Which data has high read and low write frequency?
- Which data has high write or update frequency?
- Which joins occur more frequently?
- Which parts of the application have clearly defined requirements and design?
The first three questions help us to determine where models might belong in different services. The last question helps to decide whether they remain in the Rails app.
Service and API Design
Partitioning Functionality into Separate Services
Strategies for splitting up the functionality of the model layer into services:
- Iteration Speed
- Logical Function
- Read / Write Frequency
- Join Frequency
Identify the parts of the application that are core and unlikely to change.
Is there a process that runs outside the request/response life cycle?
Views and Controllers can also be partitioned based on logical function.
Read / Write Frequency
Different data stores are optimized for different behavior. You can optimize for either read or write.
- Replicate data across services using messaging system to de-normalize data.
- Put in a single place where it is needed most frequently to minimize joins.
- Version number can be part of the path of a URI or one of the arguments in a query string.
- Use the Accept headers in a request to specify the version of an API. Caching is a problem in this case.