<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>API on Journey through Cloud &amp; Code</title><link>https://gurupasupathy.com/tags/api/</link><description>Recent content in API on Journey through Cloud &amp; Code</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 25 Nov 2021 00:00:00 +0000</lastBuildDate><atom:link href="https://gurupasupathy.com/tags/api/index.xml" rel="self" type="application/rss+xml"/><item><title>Reducing Data Transfer Objects using Tuples in C#</title><link>https://gurupasupathy.com/post/2021-11-25_reducing-data-transfer-objects-using-tuples/</link><pubDate>Thu, 25 Nov 2021 00:00:00 +0000</pubDate><guid>https://gurupasupathy.com/post/2021-11-25_reducing-data-transfer-objects-using-tuples/</guid><description>&lt;p&gt;&lt;img loading="lazy" src="https://gurupasupathy.com/img/1__o63lCwtjwCbbGw__KrUl__sw.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;I have come across quite a few ASP.NET Core WebAPI solutions where there is a inordinate number of Data Transfer Object (&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-5.0&amp;amp;tabs=visual-studio#prevent-over-posting-1"&gt;DTO&lt;/a&gt;) classes. This results in a kind of class explosion which I think can be avoided. Yes, DTOs do have their utility, no doubt. But, many a times as the application evolves and grows, we often end up with numerous DTOs and these DTOs sometimes differ just by a handful of attributes or in some cases they are a simple composition of multiple entities / DTOs.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img loading="lazy" src="/img/1__o63lCwtjwCbbGw__KrUl__sw.jpeg"></p>
<p>I have come across quite a few ASP.NET Core WebAPI solutions where there is a inordinate number of Data Transfer Object (<a href="https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-5.0&amp;tabs=visual-studio#prevent-over-posting-1">DTO</a>) classes. This results in a kind of class explosion which I think can be avoided. Yes, DTOs do have their utility, no doubt. But, many a times as the application evolves and grows, we often end up with numerous DTOs and these DTOs sometimes differ just by a handful of attributes or in some cases they are a simple composition of multiple entities / DTOs.</p>
<p>One of the reasons we have so many such DTO classes is the need to pass data to and from repository and service layer ( between different layers of the application for that matter). In order to find a way around creating yet another DTO, I was exploring some options and realized that Tuples can be used to minimize the creation of DTOs</p>
<p><a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-tuples">Tuples</a> have been around in C# for quite sometime now. I am not sure if it is a common knowledge but I recently figured out that you could eliminate quite a few DTOs that we use to ferry data between the layers by leveraging Tuples</p>
<p>Let us take the following scenario of instance.</p>
<p>We have an API, say, GetCustomers which, <em>of course</em>, will return me the list of customers . And, we have an entity, Customer as defined below.</p>
<p>class Customer<br>
{<br>
public int customerId {get; set;}<br>
public string firstname {get; set;}<br>
public string lastname {get; set;}<br>
}</p>
<p>The API response for our GetCustomers API is as below</p>
<p>You would have noticed that the attribute <em>count</em> is expected in the response and this is not present in our Customer class. The repository layer would just return a List<Customer> but the service layer needs to pass it along with the <em>count</em> attribute to the controller. This is usually where we tend to create a DTO as below.</p>
<p>class CustomerDTO<br>
{<br>
int count;<br>
List<Customer> customers<br>
}</p>
<p>The only reason for the above class to exist is to ferry the data from repository in a format that the controller is expecting. We can eliminate this class altogether by returning Tuple as below</p>
<p>return new Tuple&lt;int, List<Customer>&gt;(result.Count,result)</p>
<p>Granted, this is a very trivial scenario and you can add the count attribute in the controller and return an anonymous type also.</p>
<p>Now consider the cases when you need a response that is aggregation of multiple custom types. For instance, if we have two API one to get customer and another to get order details we would have created two DTO for Customer and Order. If a new API is required that gives details pertaining to a particular Customer and all related Orders as response, you might have to create a new DTO again, as below.</p>
<p>public class newDTO {<br>
public int orderCount {get; set;}<br>
public int customerId {get; set;}<br>
public List<Order> orders {get; set;}<br>
}</p>
<p>The expected response is</p>
<p>This is exactly what we can avoid by using Tuples like below in the service and repository layer.</p>
<p>RepositoryLayer.cs</p>
<p>var <strong>repoResponse</strong> = new Tuple&lt;int, Customer customer, List<Order>&gt;(count,custResult, orderResult);<br>
return <strong>repoResponse</strong>;</p>
<p><em>custResult holds a particular customer’s data and orderResult will be a List<Order></em></p>
<p>ServiceLayer.cs</p>
<p>.<br>
.<br>
.<br>
<em>//Create a Tuple with three members, count, customer and orders <br>
//repoResponse is the response from your repository(a Tuple)</em><br>
(int count, Customer customer, List<Order> orderList) <strong>result</strong> = (<strong>repoResponse</strong>.Item1,    <strong>repoResponse</strong>.Item2, <strong>repoResponse</strong>.Item3);</p>
<p>return <strong>result</strong>;<br>
}</p>
<p>From the above service response, the controller can create an anonymous type as below without ever creating a DTO and return the <a href="https://gist.github.com/gurupasupathy/4d04d8352e9b2be63cee00bcfea6a3fc">response</a> .</p>
<p>return new { ordercount= <strong>serviceResponse</strong>.count, customer = <strong>serviceResponse</strong>.customer.customerId, serviceResponse = <strong>serviceResponse</strong>.orderList };</p>
<p>It should be noted that, although this approach eliminates the need to create DTO classes, it come at the cost of readability. Your method signatures may not be very elegant and readable. While DTOs will still be the right way to go in some scenarios, for others, Tuples can help.</p>
<p>Hope this helps in reducing a few DTOs at your end.</p>
<p>Cheers!</p>
]]></content:encoded></item></channel></rss>