0

Should a service making a request send all the information another service requires from the requesting service to complete the requested service's job? Or should the requesting service send as little information as possible when making a request and let requesting service decide what additional information to call back for? Or does it depend on the circumstances, like the volume of information needed?

Example

If the requesting service is Venmo and the requested service is Bank of America and the request is to withdraw money from a customer's Bank of America account and send it to another bank account, should Venmo send all the details Bank of America needs to do the withdrawal? Or should Venmo send as little information as possible, for example just Venmo's identifier for the payment request and Bank of America can call back to request additional information about Venmo's payment request?

Additional Information

I'm reading Chris Richardson's advice on Microservices https://microservices.io/patterns/communication-style/messaging.html and he seems to imply that the service that initiates a request should send all the information the service that's responding to the request needs. I see the advantages of that: 1) only one message needs to be passed between the services, which reduces the chances of a failure occurring at some point in the communication, 2) Developers also have one object to look at to know everything about how the services communicate.

However, I've noticed disadvantages in practice: The requesting service may send information the requested service does not need. For example, let's say Venmo passes everything Bank of America needs. Now, Venmo wants to work with a bank in a country with high levels of money laundering. This bank needs not just the ordinary payment request but needs Venmo to send information verifying the identity of the people the payment request is for. Now Venmo has to either modify its standard payment request message to contain the identity verification information or banks that need the additional information need to request it. Now we are in a state where the requested service is requesting information from the requester and our communication flow is not as simple. Instead of having one request that contains most of the information from Venmo, Venmo could provide just an internally generated request id, expose a few APIs, and banks can use whichever APIs they need. It will require more messages between the services, but it takes the responsibility totally off of Venmo except for exposing its data to banks.

6
  • keep in mind .. it creates a circular dependency within the API call.. e.g If Venmo calls "Bank of America", which in turn calls Venmo... if Venemo server response becomes latent then it will inturn makes "Bank of America" API call latent due to circular dependency.... And with large number of parallel request it can become a big problem.. Hence i don't recommend circular dependencies. Oct 20, 2022 at 12:36
  • 2
    but it takes the responsibility totally off of Venmo except for exposing its data to banks. Hello, I'm the Bank's CTO and in no meaningful or reasonable scenario my bank is going to send requests to 3rd parties services to fulfil the contracts of my own service. It's me providing a service to you, not otherwise. Feel free to do so or look for another service provider (bank). Best regards!
    – Laiv
    Dec 5, 2022 at 13:36
  • Why should Venmo have only one service for making requests to banks? I would assume that a good microservice architecture would have one service for each thing - one to make requests for Bank1, another to make requests to bank 2, etc, each one talking with their targets at a specific standard and all that. A microservice can't really be micro if it is doing many things at once.
    – T. Sar
    Dec 6, 2022 at 14:37
  • @T.Sar The terms "good" and "thing" in your comment are not engineering terms and are not well-defined. If you figure out what those mean you might be able to answer your own question. Personally I think the idea of adding a new microservice each time you add a new bank is not an architecture that would scale out with new business.
    – John Wu
    Dec 7, 2022 at 0:34
  • 1
    @T.Sar True, banks are not added to the real world very often. But there are added to fintech systems all the time, usually by adding a tenant record and some config. Not by standing up a completely different service. That would be a bizarre design that, again, would not scale. I do not think "clean" is well defined either. Engineering decisions require variables that can be specified, measured, quantified, such as TCO, performance, time to market, etc. "Good" and "clean" do not lead to productive discussions or defensible analyses, and I encourage everyone on my teams to avoid them.
    – John Wu
    Dec 8, 2022 at 22:07

4 Answers 4

1

Should clients send all required information to servers?

No

Should Venmo send all the details Bank of America needs to do the withdrawal?

Financial institutions (FIs) generally do not interact directly with each other for money movement transactions. They interact with financial networks, such as the ACH (Automated Clearing House) network or the Visa network.

To submit an ACH transaction, an FI would need to submit

  • Source RTN and account number
  • Target RTN and account number
  • Amount
  • A short memo field, which can contain a reference number

That's it. There's no information about either bank other than their identifier. It's the responsibility of the clearinghouse to know which ID goes with which financial institution and how to contact them.

To submit a Visa transaction, a merchant can submit a bare minimum of

  • Merchant identifier
  • Card number
  • Amount

A merchant might also submit

  • Cardholder name
  • CVV
  • Expiration
  • Postal code
  • Full address
  • Phone number

The reason for submitting the additional information is not to save the Visa network data retrieval operations. The Visa network will retrieve that information regardless. The additional fields are additional authentication parameters, fed into a risk engine and compared against the correct values; the transaction is accepted or declined depending on the risk level (the reality is more complex than this explanation but this is the gist of it).

So in both cases, other than the information the caller needs to provide to signal its intentions, the APIs are getting their own information from their own trusted sources. The reason for this is pretty obvious-- if they just trusted the caller, the information could be incorrect, and could constitute an insecure direct object reference, which is a security vulnerability.

In general APIs should require only the minimum parameters they need to understand the caller's intent. The API itself is responsible for getting any supporting information.

0

I don't presume to know what the linked article thinks, but there may be two different things here.

According to REST the client should send all the information the server requires to process the request. However, this is a technical requirement, not a semantic one. It means that the request should carry its type and all the contextual information needed, specifically not relying on previous communication, so that the server knows how to deal with it technically.

The server may very well "deal" with the technically complete request by asking back: hey, I need some more data to semantically complete the request. Or by directing you to log in. Or issuing an error related to the meaning of your request. Those are all considered technically "handled" requests.

Note however, if the server asks an additional question (pops up another form, etc.) the next request needs to contain all information until this point in the conversation again. I.e. requests should be stateless and not rely on previous communications.

Beyond these technical constraints, what the request really means, what it contains specifically, what the workflow is, if any, is up to you.

1
  • I"m looking for evidence and advice on architecture best practices.
    – user7340
    Oct 19, 2022 at 16:33
0

If you're going Microservices, keep them Micro.

Assume we have two banks, B1 and B2, with wildly different APIs.

One can be online while the other isn't. Updates to them will be done at different times. They have different request procedures.

So, break your services up:

WithdrawMoneyService is the general service for taking money out of banks accounts. It either calls one of those:

  • WithdrawMoneyFromBank1Service
  • WithdrawMoneyFromBank2Service

Which, in turn, know how to talk to their specific banks (and only to those specific banks), and send only and all the information needed by that bank to make that specific requests.

If a third bank is added, then a third service is raised:

  • WithdrawMoneyFromBank3Service.

And so on.

Keep your microservices Micro. If they're having to the same thing in two different ways, that's a strong smell that they might have to be broken into more, smaller services.

-1

The difference is performance and security. If you send a limited amount of data, a fake server (like a real one) would have to send a request back, and you might be able to detect it is fake. I think this is not a great advantage, making sure you are talking to the right service should be done independent of your code.

If you send all the information you think is needed, that might be too much; you might send unneeded data which is just waste of time. If you don’t send everything needed, you have one added data round trip.

I would try to send exactly the data that is needed, and log requests to send more data. Then update the code if some data is regularly needed and not present. But if you send 1000 requests and 50 ask for missing data, that’s not optimal but not that important to fix.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.