1
\$\begingroup\$

I'm attempting to integrate with a rather dated API (for work so I can't disclose actual naming, endpoints, etc), and their data models for POST endpoints, very clearly implement an interface that looks similar to:

public interface IExternalData {
    int CallerId { get; set; }
    string CallerName { get; set; }
}

When I say they very clearly implement an interface, I can make this assumption based on the fact that all of their data models contain roughly 5 properties that are exactly the same. With that being said, none of the endpoints return data, so all of the models are simply the data expected to be sent to their respective endpoints.

Now, I could create an interface to implement that, but, I don't think that it's necessary in this particular case. Instead, what I'm thinking about doing is introducing a packet model that represents the interface, plus a generic property to represent the individual models, and an additional property that translates the structured data back to a flat model, respective to endpoints:

public sealed class ApiPacket<T> {
    public int CallerId { get; set; }
    public string CallerName { get; set; }
    public T Data { get; set; }
    public Dictionary<string, object> KeyValuePairs {
        get {
            var dictionary = new Dictionary<string, object> {
                { "CallerId", CallerId },
                { "CallerName", CallerName}
            };
            string serializedData = JsonConvert.SerializeObject(Data);
            var data = JsonConvert.DeserializeObject<Dictionary<string, object>>(serializedData);
            foreach (string key in data.Keys)
                dictionary.Add(key, data[key]);

            return dictionary;
        }
    }
}

The only thing this really saves me from however is having to implement the same ~5 properties across all of the data models (there are about 40 of them that I need to create). So, while it's redundant, it's not really hurting anything to create the interface and refrain from introducing complexity.


Does my structured implementation raise any concerns over utilizing an interface, given that the use-case is for posting data only, not receiving it?

  • My educated guess is yes due to unnecessary complexity, and that I should go the interface route, but I'd like some community feedback before I make a hard decision to go either way.

Q&A from Comments

@iSR5 asked:

in basic terms, you need to unify the POST endpoints data models with one model instead of having multiple different models ? if so, why? what advantages and disadvantages that you get doing so ?

I wouldn't say that I need to unify them entirely, but I think I understand your point. The advantages, in my mind, are that it's easier to maintain the unified model, expansion is simplified, and most of all, I don't have to copy and paste across 40 models. The biggest disadvantage I can think of is with regards to a new endpoint being added. If myself or someone else comes back to create the new model, will it be known that the structured model exists? If not, then it could potentially duplicate keys in the JSON, but it should explode at runtime in that case.


Note: To clarify, these models don't exist in my code yet and that's why I'm here.

\$\endgroup\$
0
3
\$\begingroup\$

UPDATE

Thank you for adding more clarifications. Since you're working with a web service. There are some questions that I've asked myself with your solution.

If the Web API provider updated their endpoints with new keys, do you need to add them to the current solution as well ? if yes, then what purpose the dictionary serves here ? what you will do on each update ?

The current solution seems to handle the response (or request body), what happens after that? do you have such handler to handle the generated data elsewhere ? if yes, does this handler scoped to this class or is it used also for different objects ?

Current solution definitely better than handling 40 different models, however, these questions you should think of them as a way to increase the stability of your chosen solution to know how much time and efforts you need to stabilize this solution.

Here are some things that I need to mention (just a heads up):

  • using object would add more boxing and unboxing, so you'll always need to cast the values to their respective types.
  • using JsonConvert will always add Json.NET as a requirement to this solution.

Lastly, I suggest you change the name of the class to include the provider name and the purpose of this class (e.g. ServiceProviderNameResponseResult ). This would give more clarity to the code, so from its name anyone would know it's related to that provider, and what it handles.


Old Response

While your approach is more maintainable, flexible, and also would reduce the code complexity, it would also add more time and efforts to the project itself as code refactoring always has hidden fees!

When trying to apply a new design change on a tested, and released code, you are actually adding more developing, testing, and maintaining to the new design, and introducing new bugs as well.

So, it's not only the case that if someone works on it would know about this change or not! It's about the cost of time, efforts, and management as well.

What I think, and what I would do if I was in your shoes: if refactoring is necessary, I would try to avoid adding new classes, and use what .NET offers - like using the IHttpActionResult or HttpResponseMessage classes instead. This would be easier to maintain, and easy to grasp!

If there is too much work to do, then DelegatingHandler might be the solution. It's a useful handler, as it intercepts each request/response and delegates them to another handler. So, you can create a handler to handle all requests/responses without changing any controller.

\$\endgroup\$
4
  • \$\begingroup\$ So I think there might be a misunderstanding. I'm not refactoring an existing system (though I can see how you arrived at that conclusion), I'm creating the data models for our system to integrate with an existing system, so the models on our side don't exist yet. \$\endgroup\$ Aug 18 '21 at 19:22
  • \$\begingroup\$ @Tacoタコス so you're working with a web service ? something like Google API or similar services ? \$\endgroup\$
    – iSR5
    Aug 18 '21 at 20:17
  • \$\begingroup\$ Precisely, and the company that owns it still adds to it while remaining consistent with their current conventions. \$\endgroup\$ Aug 18 '21 at 20:29
  • \$\begingroup\$ @Tacoタコス thank you for this clarification. I updated my answer. \$\endgroup\$
    – iSR5
    Aug 19 '21 at 19:50

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.