Profile Service
The Profile Service is a microservice that extends the domain data of the legacy Customer Service. This is the microservice that is strangling the domain data of the Customer Service—and in the process—slowly transitioning the system of record away from the large shared database in the legacy system. The Profile Service exposes protected domain resources as a REST API, using the Spring Cloud Security project to implement the OAuth2 client workflow.

1 | |
In the code snippet above we see the ProfileControllerV1 class, which is a REST controller that provides an endpoint for retrieving the Profile of a user. The Profile object we are retrieving here will extend fields from the Customer object, after retrieving domain data from the legacy Customer Service. To do this, we will call directly to the Customer Service in the legacy application zone using a SOAP client.
1 | |
In the snippet above we find the definition of the CustomerClient. This class will provide the Profile Service with a capable SOAP client that can retrieve a Customer record from the legacy Customer Service. We’ll use this client from the ProfileServiceV1 class below to retrieve the Customer domain data that we will be extending in the Profile object.
1 | |
The code snippet above contains the definition of the ProfileServiceV1 class. This bean will conditionally call the legacy Customer Service by making a SOAP request from the CustomerClient. The getProfile method is called by the ProfileControllerV1 class, returning a Profile object that extends domain data from the legacy Customer object.
1 | |
As a part of this workflow, the Profile Service looks to its attached MySQL database using the ProfileRepository to find a Profile record with username as the lookup key. If the Profile for the requested user does not exist in the database, a request to retrieve the Customer object is made to the Customer Service. If the Customer Service returns a Customer record in the response, the base domain data returned from the legacy Customer Service will be used to construct a new Profile record, which is consequently saved by the Profile Service to the attached MySQL database.
Using this workflow, the Profile Service only needs to call the legacy system once for each Profile that is requested. Since we’ve re-routed all requests from other legacy applications to use the Legacy Edge Service, we can safely transition the system of record for domain data away from the legacy Customer Service without performing any risky database migrations. Further, to support backward compatibility in the “large shared database”, we can replicate any updates to the base Customer domain data by scheduling tasks asynchronously to call the Customer Service when a change is made to a Profile.
1 | |
The snippet above is the implementation of updateProfile. In this method we are receiving a request to update the profile of a user. The first step is to ensure that the profile being modified is the user who is currently authenticated. To make sure that only a user that owns the profile can update the domain resource, we check to see if the requested change is different from the profile of the authenticated user.
|**|To support backward compatibility with the legacy system, we’ll need to support a different workflow for validating the authenticated user, since the Legacy Edge Service uses client_credentials for authorization.|
After updating the profile, we need to replicate the write back to the customer service. To make sure that the cloud-native application is able to scale writes without dependency on the legacy system, we want to be able to durably replicate the write in an async workflow. By sending a durable message to a RabbitMQ queue, we can use the Profile Service to send back updates to the Customer Service asynchronously without tying up thread and memory resources of the web server.
1 | |
The snippet above is our message listener on the Profile Service that will asynchronously issue writes back to the Customer Service in the legacy system. Since the network is prone to failure, this workflow ensures that there will be no loss of data since the RabbitMQ message can only be acknowledged after an attempt to update the Customer Service was a success.