Microservices: How the databases organized behind the microservice - database

This is my first time reading about the microservices. Knowing that services is a subdivide system from a whole system which specialize in different domains. What about the data. I assumed all services using tradition db to store their data and data are stored distributed in different domain. What if there are data can belong in both of these domain services, what should I do with them.
E.g. A basket service (handling user shopping cart), and Payment service (handling payment of their order they have placed in the basket).
Maybe this isn't a great example, where do the product information to be stored.
In monolithic application, we have single database which stored the whole business data where each data will have reference to each other.

With the services we tend to ask one question who is source of truth?
In your case user adds item to the cart and there is service which keep tracks of what items the user has added (it may just have a itemid stored)
When this used to moves to checkout, there will be a checkout service which will then ask the cart service about the items in the users cart, apply in the cart logic.
Thing to note is checkout service knows and care about the checkout process and it has no idea where to get the data of the items. Its just calls the right service and get the stuff it wants and apply the logic.
For checkout to payment you pass along userid cartid and other info and payment can make use of these information to bloat the information as it sees fit and return a response back to checkout which may trigger an order service.
So if you see data is always available with one service and when ever you have a situation where you need data, instead of making a db call you make a service call
(Service responsibility is to give you this data with low latency and may be pulling in logic to cache or whatever)
Another point with respect to data is source of truth. For order service, which is called often we tend to keep a copy of all the information related to the order in it (Again we do that, their may be better approaches) and in doing so often during a return flow question which system to trust.You may query an order service to get an address on which order is supposed to be shipped, but this address might have been deleted by the user.
This is where Single source of truth comes into play. This is little tricky, for delivery service source of truth for delivery address is what it gets from order service and not the user service (however order service picked up the details from user service at time of placing orders)
At the same time, during return flow we consider the prices as stored in order service (again a snapshot of what was there during the time order was placed) not necessarily make a call to product service, however for payments we talk to payment service directly to check amount we have taken from the user (There may be multiple inward and outward flows)
So bottom line is
Have one database exposed via one service, and let other service connect to db via this service
Read more about Single Source of Truth. We decided on certain contracts like who is the SSOT for whom (I do not necessarily agree with this approach but it works well for us)

Related

How to query data from different types of databases in a microservice based architecture?

We are a using a micro-service based pattern for our project where we have Users and their Orders. Users personal information (name, email, mobile) is stored in User table in relational database while we are storing Orders data of users in Orders collection in NoSql database. We want to develop an API to get a paginated list of all the orders placed with order details along with finer details of user associated like - user name, mobile, email along with each order. We are storing userId in Orders collection.
The problem is how do we get User details for each order in this list since both the resources are in different databases. We also thought of storing user name, email and mobile in Orders collection only but what if a user updates their profile, the Orders collection will have stale user data.
What is the best approach to address this issue?
You can use API gateway pattern, UI will call to API gateway endpoint and the Endpoint will call the both the API/services to get the result and aggregate it then returns aggregated response to the UI (caller)
https://microservices.io/patterns/apigateway.html
Well it mostly depends on scalability needs in terms of data size and number of requests. You may go with the API gateway if you don't have too much data and you don't get many requests to that service.
Otherwise if you really need something scalable then you should implement your own thought with an event based communication.
I already provided an answer for a similar situation you can take a look
https://stackoverflow.com/a/63957775/3719412
You have two services Orders and Users. You are requesting Orders service to get all Orders. It will return a response data which will contains ID of Users (each Order contains ID of User). Then, you will make a request to a Users service to get an information regarding User by ID which you got before. And finally, you can aggregate those results (if it is needed).
As guys mention, good solution will be to implement API Gateway here. As a client, you will send a request to a single port with endpoint (to a Gateway) and Gateway should create logic which I have described before.

Business logic wrapped inside a db transaction

In my app i have an api layer that defines routes, services layer to perform business logic, and a repository layer that queries the database. Services will call into the repository layer to retrieve data, perform various business logic and then return a response back to the api layer.
Now, I have some business logic that needs to be completed inside a database transaction. For example, let's assume my app allows you to buy tickets to a given event:
Service layer calls repository to atomically reserve tickets in the db by decrementing number of available tickets.
Service layer then makes an api request to process the payment for the ticket.
If the payment succeeds, service layer calls repository to create an "order" for the user and the given event.
If the payment fails, however, i want to rollback the changes made to the ticket availability. (or if for some reason creating the order for the user fails, same thing).
The problem is that it seems like a leaky abstraction if the services layer is aware of database transactions. Is there a better paradigm for this?
You don't want to hold a database transaction open the whole time you are making an API request anyway... You probably want to insert a 'pending' order, then once you get the payment change the status to 'confirmed'. This lets you store details about the error and report on failed payments too

When and how should I check what active organisation a user has?

I am building a hybrid mobile app using AngularJS and Ionic as front-end.
Each user belongs to an organisation. But it is possible to change which organisation a user belongs to on the server and in a different web application.
The user can do some things in the web app:
Get data about the organisation
Post, put and delete data about the organisation
Each of these requires an API call to get the relevant information.
Now my question is, when and how should I check which organisation the user belongs to?
Should I send an API call before every get, post, put and delete to check which organisation the user belongs to?
If yes, then what it a nice way to organize this organisation checking without having it tangle up all my other code?
It sounds like what you're trying to get at is permissions for the user to edit, etc. the organization only when they belong to it. That should be done server-side for the following reasons:
It keeps the access control coupled to the operation, so the server can prevent disallowed reads/changes even if there's a bug in the client.
It stops malicious users from bypassing the membership check altogether, which they can do if the client is all that's enforcing the rules.
It avoids the API calls you're worried about that constantly need to recheck the user's membership, as well as the race conditions if membership changes between the check and the next call.
It handles both your Ionic client and your other web client, and lets you expand to more clients in the future, without each having to duplicate the checking logic.
Similarly, it lets you modify your permissioning logic in one place, for example if you wanted to differentiate users who can read the organization from admins who can edit it.
Once the server is solid, there are only a few places you'll need to sync the user's memberships:
At app startup, unless you keep a cache from the last use and that's good enough.
On some schedule as they use the app, if memberships change frequently enough that you want to sync quickly. Perhaps whenever they visit their list of organizations.
When the user does something in the app to invalidate the cache, like join or leave an organization.
When an API call about an organization fails, because the user may no longer be a member.

Is it better to process auto-complete/suggestions on the client or server?

I am building a web app that will use an auto-complete/suggestions for the end user as they type their information in. This will be specifically for entering Country, Province, City information.
Do a wild card search on the database on each keystroke:
SELECT CityName
FROM City
WHERE CityName LIKE '%#CityName%'
Return a list of all Cities to a given Province to the client and have the client do the matching:
SELECT CityName
FROM City
WHERE ProvinceID = #ProvinceID
These would be returned to the client as a JSON string via an ajax call to a web service. My thoughts are that javascript would be able to handle the list of 100+ entries via JSON faster than the database would be able to do a wildcard search, but I'd like the communities input.
In the past, I have used both techniques. If you are talking about 100 or so entries, and assuming each entry is very small, it will likely be faster to do the autocomplete filter on the client side. That will provide you with better response time (although probably negligible) and will reduce the load on your server.
Google actually does a live search while the user is typing, and it seems to be pretty responsive from the user's point of view. This is an example where the query must be executed server-side because the dataset is far too large to transfer to the client.
One thing you might do is wait until the user types two keystrokes before fetching the list from the server, thus narrowing down the results initially. Of course, that adds complexity - you would then need to refresh the list if the user changes either of the first two keystrokes.
We have implemented same functionality using ajax auto complete control we wait the user type three keystroke before fetching the list from server we have not done any coding at client side we just assigned web services method which return list to ajax control and its start working
In the end user's interest, it is always better to handle this client-side.
The Telerik Autocomplete controller allows for both ways.
Of course under load client-side autocomplete is likely to make the application crawl.

Implement a paid subscription service on a website

I have a website and I would like to implement a paid subscription service. Its a simple service with only 2 types of plans. For now, ill just use Paypal. But im a little lost before start, mainly with the data model.
My main question for now is, what information do I need to keep for each subscription? Do I need to implement a shopping cart for this (dont think so)? Im not asking for a detailed explanation, just a few lights or resources to find a way to start. Thanks.
Depends on what technology you're using. Basic payments work a bit like this
-> You send them to paypal with a plan (you define the plan on paypal)
they know which amount to charge
you can pass custom parameters which they will pass back
Customer fills in application
<- paypal tells you that your predefined plan got purchased
in this same request, they send a lot of info about the payment including a GUID and your params
-> you ask paypal "hey, some one just told me this plan GUID got purchased, can you confirm"
<- paypal service returns 'yes'
-> you take the customer's ID from the params that you attached when you sent them to the paypal service and update them to "paid" in the database, or whatever
That's it in a nutshell...
Look at any subscription card mailer from any magazine and you can get an idea of what kind of data you will have to record. Start and end date for the subscription would be a good thing to keep, and what kind of plan the user is subscribed to. Once you have the end date, you just need to run a query to get the records of the users that have access. Something like
Select * from users where subscription_end_date is >= today
I'm sure there will be a lot of other columns that will go into your final product, but that will be up to you to decide what data you want to keep. What are the different states that a subscription can be in? Can someone be subscribed to both services at the same time?
PayPal does a decent job if you want to charge the same amount every month. However, if you anticipate your users making changes to their subscription plans (upgrades/downgrades) or needing to provide credits to their account for customer support purposes, PayPal would require that you cancel the subscription...and then have the customer re-subscribe.
[Full disclosure - I am a co-founder of Recurly.com]
Recurly handles the upgrades and downgrades, and provides automated customer emails to be sent out to your customers (on your behalf) for every event confirmation, and invoice that occurs. You also have a full account management dashboard and reporting so that you don't need to build this yourself.
Best of all, if you ever decide to leave PayPal, and move your business to a standalone payment gateway, Recurly stores all of your credit cards in a PCI compliant vault so you don't need to ask you customers to come back and re-subscribe. (PayPal will not return your customer credit card information). You simply configure your new gateway in Recurly, and payments will be processed without any interruption to your business.
Here is a blog post we wrote on the topic:
http://blog.recurly.com/2010/08/top-ten-reasons-to-use-recurly-vs-paypal-for-recurring-billing/
-Best of luck.
-Dan

Resources