Business logic wrapped inside a db transaction - database

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

Related

How to add multiple subscription in Azure Logic app Service bus topic trigger

As I am having a logic app where the trigger is service bus topic subscription. I want to add multiple subscription ("A", "B","C") for the given topic in my logic app service bus topic trigger . Whenever i select topic it only allows me to select single subscription. Is there any way to add multiple subscription from an array or static variables ? if yes then how to add conditions ? I tried using array, but i have to provide the index of the subscription.
I can use multi trigger logic app for all of the subscriptions to achieve what I am looking for, but is there any other way like using some wildcard characters ***** or / or something else which i am not familiar with .
The action supports selecting only one subscription as you have observed.
Multi Trigger Logic App is indeed one way to go about it but note that the designer doesn't support them, and you will be forced to edit only using the code view.
One alternative would be to split your logic app into two
one for your business logic that is triggered by a HTTP request
one (or more) that is triggered by the service bus subscription trigger and calls the first logic app
Another alternative is to leverage the Event Grid Integration in Service Bus, but note that this is currently applicable only for the Premium Tier.
In this approach, the logic app would trigger based on an event message from Event Grid with details of the subscription that has messages ready to process. You would then use the Get messages from a topic subscription action to fetch the messages to process.

Microservices: How the databases organized behind the microservice

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)

What is the best practices for building REST API with different subscribers (companies)?

What is the best design approach in term of security, performance and maintenance for REST API that has many subscribers (companies)?
What is the best approach to use?:
Build a general API and sub APIs for each subscriber (company), when request come we check the request and forward it to the sub API using (API Key) then retrieve data to general API then to client.
Should we make single API and many databases for storing each subscribe(company) data (because each company has huge records that why we suggested to separated databases to improve performance)? when request come we verify it and change database Connection String based on client request.
Should we make one API and one big database that handle all subscribes data?
Do you suggest any new approach to solve this problem? We used Web API and MS SQL Server and Azure Cloud.
In the past I've had one API, the API is secured using OAuth/JWT in the token we have a company id. When a request comes in we read the company id from the JWT and perform a lookup in a master database, this database holds global information such a connection strings for each company. We then create a unit of work that has the company's conneciton string associated with it and any database lookups use that.
This mean that you can start with one master and one node database, when the node database starts getting overloaded you can bring up another one and either add new companies to that or move existing companies to take pressure off. Essentially you're just scaling out when the need arises.
We had no performance issues with this setup.
Depends on the transaction volume and nature of data, you can go for a single database or separate database for each company.
Option 2 would be the best , if you have complex data model
I don't see any advantage of going for option 1, because , anyway general API will call for each request.
You can use the ClientID verification while issuing access tokes.
What I understood from your question is, you want an rest API for multiple consumers(companies). Logically the employees from that company will consume your API, employees may be admin, HR etc. So what I suggested for such scenario you must go with single Rest API for providing the services to your consumers and for security you have to use OpenId on the top of OAuth 2. This resolves the authentication and authorization for you.

Handling multiple commands as transaction

Im currently developing payment system which performs payment and writes that item is bought in cloud hosted database, Azure.
How it works currently is:
Transaction with 3rd party payment system
If success, new subscription row in database is added for the user
Transaction history and other relevant stuff is written into database
However, in an unlikely event that:
Transaction is success(http call to payment gateway returns success)
For some reason, insert in database fails
I will end up with the user having paid for an item without the actual subscription for the item.(since the row wont be in our database)
These two calls are not database related (one is, another one is simple async http request) so I cannot treat them as transaction( since I cant really rollback ).
So my question is for more experienced how to handle this situation?
To answer, I've implemented this using Compensating Transaction pattern.
Works as expected

AngularJS: combine REST with Socket.IO

In the single page webapp I've recently built I'm getting data for my models using Restangular module. I'd like to add real-time updates to the app so whenever any model has been changed or added on the server I can update my model list.
I've seen this working very well in webapps like Trello where you can see the updates without refreshing the web page. I'm sure Trello webclient uses REST API.
What is a proper way to architect both server and client to archive this?
First of all, your question is too general and can have a lot of solutions that depend
on your needs and conditions.
I'll give you a brief overview for a single case when you want to leave REST APIs
and add some realtime with web sockets.
Get all data from the REST -- Sokets for notifications only.
Pros: Easy to implement both server side and client side. You only need to emit events on the server with
info about modified resource (like resource name and ID), and catch these events on the client side and fetch
data with REST APIs.
Cons: One more request to the server on every notification. That can increase traffic dramaticaly when you have a lot of active clients for a single resource (they will generate a lot of reverse requests to the server).
Get initial load from the REST -- Sockets for notifications with data payload.
Pros: All info comes with the notification and will not cause new requests to the server, so we have less traffic.
Cons: Harder to implement both server side and client side. You will need to add data to all the events on the server. You will need to fetch data from all the events on the client side.
Updated according to the comment
As for handling different types of models (just a way to go).
Client side.
Keep a factory for each model.
Keep in mind that you need realtime updates only for displayed data (in most cases), so you can easily
use memory caching (so you can find any entity by its ID).
Add listener for every type of changes (Created, Updated, Deleted).
In any listener you should call some initObject function, that will find entity in the cache by ID and extend it, if there is no entity with such ID, just create a new one and add it to cache.
Any Delete just removes an entity from the cache.
Any time you need this resource, you should return the link to cache object in order to keep two way databinding (that is why I use extend and not =). Of course, you need to handle the cases like: "User is editing the resource while notification about deleting comes".
Server side.
It is easier to send all the model then just modified fields (in both cases you must send the ID of resource).
For any Create, Update, Delete event push event to all engaged users.
Event name should contain action name (like New, Update, Delete) and the name of resource (like User, Task etc.). So, you will have NewTask, UpdateTask events.
Event payload should contain the model or just modified fields with the ID.
Collection changes can be handled in two ways: with add/update/remove items in collection or changing all the collection as a whole.
All modifications like PUT, POST, DELETE are made with REST of course.
I've made a super simple pseudo gist for the case 1). https://gist.github.com/gpstmp/9868760 but it can be updated for case 2) like so https://gist.github.com/gpstmp/9900454
Hope this helps.

Resources