Data Transfer Object
Tags: typescript, webdev
Published: 2021-03-08 18:35:39

Good day guys, I stumbled accross something that moved me to write this article, i had to  work with and transfer data i was getting from the user to a DTO, it was quite new to me so i made a little research on the subject and i decided to share my findings and how i implemented a DTO using TypeScript. You have to be conversant with TypeScript to understand this article.

## What are DTO's
A DTO is an object that can be used to transfer data through processes, a process in this case is usually a communication between a client and a server. This process is quite expensive because it will take some time for a single request/response process between the client and the server. To negate this, we can reduce the amount of calls to the server by transfering data between the client and the server in such a way that it is the representation of the different calls we would have made over time, inside a single object.

DTO are also usefull when deciding how we persist our data in a database, it would be nice if we can have a client representation of data in a manner that is backwards compatible with how the data is stored in the database, in literal terms the frontend data should mirror the backend data. This allows us to easily upgrade our application since the way data is represented in both the database and the frontend is consistent thus we will not need to edit our data, except we want to add a new property to it, and it's still easier to maintain. 

I will skip the installation and set up of typescript because the scope of this article covers only DTO and not TypeScript, i will assume we already have a typescript project set up and we want to use a DTO to accept data and transfer it to the server.

### Creating A DTO
A DTO is an object that has no methods, only properties. We are going to create a user and that user should have the following;
* firstName 
* lastName
* email
* budget
* phoneNumber.

How does this helps us? We can create an interface that will define a contract all users need to fulfill and really any object that says it is a user should implement the interface. Let's go ahead.
```typescript
// user.interface.ts

export interface User {
 firstName : String;
 lastName: String;
 email: String;
 budget: Number;
 phoneNumber: Number
}
```
We can now create a class that will implement the user interface.

```typescript
// user.ts
import { User as UserInterface } from './user.interface.ts'

export class User implements UserInterface {
 constructor(public firstName: String, public lastName: String, public email: String, public budget: Number, public phoneNumber: Number){
 }
}
```

Now whenever we want to create a new user, we are sure it will hold only the required, properties. We can serialize the Instance of the class and send it to a server to be stored in a database, MongoDB, maybe?

```typescript
// index.ts
import { User } from 'user.ts';
import { User as UserInterface } from 'user.interface.ts'
//we are crrating our data ourselves here, but normally we would get it from the user

const firstName: String = 'john'
const lastName: String = 'doe'
const email: String = 'john@doe.com'
const budget: Number = 1000
const phoneNumber: Number = +2347684328

const user = new User(firstName, lastName, email, budget, phoneNumber);

// we can now send the user to the server
const storeUser = async function (user: UserInterface) {
 const res = await fetch('link to your server')
 const data = res.json()
 //do something with data
}

storeUser(user)
```

This one use case of of DTO.. Clearly what if we want to fetch the user from our database and use it in the frontend? Sometimes our server might tack on other properties to our user? How can we be sure that our app will not break? we can use the user class we defined earlier to ensure that we get the data our app relies on
```javascript
// app.ts
import { User } from 'user.ts'

class Customer extends User {
 constructor(public firstName: String, public lastName: String, public email: String, public budget: Number, public phoneNumber: Number, public isAdmin: Boolean, public id: String){
 }
}

let customer: User

function getUserName (user: User){
console.log(user.firstName + ' '+ user.lastName)
}

const getCustomer = async () => {
  const res = await fetch('url')
  const data = await  res.json()
  customer = data
  getUserName(customer)
}

getCustomer()
```