3

I'm wondering what's the best approach, and its advantages, when specifying parameters for the Web Service methods. Best to explain it through examples.

In my (SOAP) WebService, used by a Xamarin mobile app, I have a WebMethod SubmitForm(int, TransactionData, List<Answer>), where:

int is the ID of the Project and specifies which Database to connect to,

TransactionData is a DTO containing data about the user and the form, and

Answer is a DTO containing the ID and answer for a single question.

Because I have separate tables for TransactionData and Answers, these are fairly unrelated to each other, but I'm considering creating a new DTO, SubmitRequest, which would contain these 3 objects. What are the advantages and disadvantages of these options, apart for readability, and a minuscule overhead of instantiating and extracting from SubmitRequest?

Another situation to consider is a WebMethod which accepts a single primitive type, like int. Would it be better to just let it accept an int, or wrap it in a DTO, that contains just a single property? Frankly, I'm not a fan of the latter, because you end up with DTO for a string, int, etc.

Hence the question, what is the most advantageous for the system? Is there even a difference? Or maybe it's just a matter of personal preference?

2

There is a few things to unpack here:

Having multiple parameters in a method

It creates a dependency on the caller of the method because it now needs knowledge about order of parameters. Having a single parameter that semantically represents what the parameter is will help decouple things a little bit more. Use your judgment to determine how many parameters you tolerate before it's "too much".

Wrapping two models in a single model

It can go wrong or it could improve the semantics throughout your code. When you have several parameters in a method it is possible that they have some kind of affair (secret relationship), they don't know what to call it so it's up to you, they either belong to one another, one has the other, they both belong to a higher level of abstraction.

Something to add here is that your models/DTOs don't have to reflect your DB schema, therefore, just because you are putting both models in a DTO doesn't mean that they now need a Foreign Key to one-another, that is only necessary if you put one of the DTOs inside of the other.

Using a primitive method as a parameter

Is semantics worth the hassle? Sometimes it is, sometimes it's not. Do you see value in naming that a bit better? Should it be maybe a property of the infamous child product of the affair of all the parameters? Maybe. But if it's just one parameter and it's primitive... I would just whatever.

Hope this helps. Let me know your thoughts.

2
  • Very good response. Much appreciated :) I'm not sure I understood this: Do you see value in naming that a bit better? Do you mean that int or string has less semantic meaning than e.g. Age, or Name? – Jeff Nama Mar 6 '20 at 15:26
  • 1
    That is exactly what I meant. As your app evolves the use of such parameters might become very hard to "remember" what it is supposed to be and you will force people to read and understand the use of it, to infer what it is, vs just reading the parameter name. If it's just one method (beginning of the life of your app) that's a debt you can/should pay later. If you know that your app will evolve in a way that that kind of parameters will be everywhere, then you should pay it early. It all depends. – Jorge Armando Palm Mar 6 '20 at 15:36
1

To be honest, three is a lot of leeway with API design that is open to personal preference. That said, that preference should be informed by the trade-offs of design decisions. SOAP is a bit deceptive in a sense because it allows you to behave as if you have separate arguments to your function, but when you look at the serialized request it's all encapsulated in a quite verbose XML structure. Essentially, the "one DTO" that rules them all. Your framework hides that away from you.

Because of the design constraints of SOAP you have the ability to think in terms of your question. Based on what you are describe, my personal preference is to treat the SOAP API like normal Object Oriented Programming (OOP). Essentially the same thought processes you go for keeping separate objects vs encapsulating them in a larger object doesn't change simply because the method you are implementing is designed to be called remotely.

That said, there are a few caveats with SOAP:

  • Don't use SOAP to send blobs (binary large objects) as an array of bytes. That array needs to be read into memory all at once, and depending on the size may cause your API to run out of memory.
  • Be careful with arrays and very large objects. Unbounded inputs can cause memory problems just the same as sending an attachment as an array of bytes. Most frameworks don't have lazy loading or partial document loading features.
  • If possible, use pre-deserialization validators to protect your API from DOS attacks. Essentially, if the whole package for a request is above a certain number of bytes it should be rejected out of hand. Many web servers allow you to specity a maximum request size. Malicious people can exploit bad error handling by sending a package that is too large to process.

The story does change somewhat with JSON. The reason you need a parent request object in JSON is because there isn't a standardized encapsulation around your arguments like you have in SOAP. Honestly the same caveats I shared above with SOAP also affect JSON. However, I haven't run across JSON APIs in the wild that violate those caveats like I have with SOAP.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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