Explore the differences between using data models and data transfer objects to get data in and out of your services.
- [Instructor] There are different ways of getting and returning data in a Web API service that I'd like to compare and contrast for you so you can see when each option is the right one to use. The first one of those two options that I'm going to show you is called models, which you could also call a record or a data model, or even an entity. Basically these are all different ways of saying that you're sending and receiving an object that represents an entire row from a table in your database, serialized and deserialized between an object in JSON. There are situations where you might want to do this, like when you create a very generic API to be used by many different applications.
For example, imagine creating an API that could be used by different customers to create custom integrations into your system through the API. In this case, you might want to have the API return entire database records exactly as they're stored in the database and let the client application decide what to use and what not to use. However, more often I find that APIs are being purpose-built for a single consumer, or at least only a few known consumers like mobile app and a web application.
When you are creating an API like that, it's much better to design your API to send and receive only the information that it needs. The reason for this is that applications that send and receive data to a REST API can very quickly start to overwhelm their available bandwidth, ultimately slowing down the application. In my experience this is the number one cause for slow API consuming applications, too much data being sent over the wire. Another benefit of the DTO is that you will sometimes have fields that you don't want to send either because you're going to hide them to make them uneditable, or for security reasons.
In that case it can be helpful to completely remove the sensitive data from ever being sent over the wire or from being sent in for an update. The solution to both of these issues is to change the shape of the data going in and out of your application removing anything that's sensitive and sending only the data elements that are required back and forth over the wire. These slimmer objects are often called DTOs, or Data Transfer Objects, because their reason for existence is only for transporting data in and out of the API.
Their relatively small size allows them to use less bandwidth, often resulting in a faster application. In previous videos we looked at several examples that used DTOs. When we looked at those, you may have already been familiar with the concept of DTOs, but if not, you were probably wondering what they were all about, so let's look at them in more detail. Data transfer objects are simple objects that include only the data elements we need to send and receive over the network. Typically in .NET, these objects are POCOs, or Plain Old CLR Objects, not inherited from any base class or using any frameworks.
They usually only include simple fields or properties with no methods that do any kind of actions. Let's look at an example where we might want to use a DTO for security reasons. Notice that the results in Postman for getting all tours also returns a note that is supposed to be for internal use only. We might not want to publish this sensitive information through the API, so let's create a new DTO for the tours.
We'll call it Tour DTO. Notice that it's just a Plain Old CLR Object, not inheriting from any special base classes. Now let's copy the properties from the tour entity into the DTO. Let's remove all the attributes and most importantly, let's remove that note that we didn't want to expose through the API.
Back in the Tour Controller, let's change the return type of our list to a list of tour DTO, and then we'll have to do some mapping from tour to tour DTO in a Select statement. And we're gonna go ahead and map all of these to a new tour DTO, which means we'll want to set each of the properties of the tour, including the description, the name, the price, and the tour ID.
Notice that we've purposely left notes off of this list. Now when we request a get for all tours from the tours API, notice that we no longer have any notes in the results. Now you've seen how Data Transfer Objects can be used in the place of models or data entities to both speed up and secure an API. We also looked at a specific example where we removed some sensitive information from a response, using a DTO.
Next we'll look more at the option of using models directly in our controllers.
- Convention-based routing
- Binding your code to an HTTP request
- Validating models
- Using attributes to route requests
- Customizing attribute routes
- Data serialization and model binding
- Error handling
- Using exception filters and exception loggers
- API documentation and testing
- Securing your API