In this video, Nate explains how to create a class to represent an ION hypermedia link between resources.
- [Narrator] Earlier, we used the URL dot link method in a controller to generate an absolute URL to a resource. This method isn't available outside of a controller, so we'll need to find an alternate way for our service code to represent links between resources. As a first step, let's create a simple model of a link. The Ion specification describes three parts of a hypermedia link. First is the href, which is an absolute uri to the resource, or route. Second is the method, or HTTP verb that should be used to interact with the resource.
And, third, is the relation type, which can be self, collection, form, et cetera. The Ion specification defines a number of link relations that are possible. Out of these three, only the href is required. The others are optional. In our project, I'm going to create a new model called Link. And here, we can add those properties. We'll add a string for Href, we'll add a string for Method, and we'll add a string array for Relations.
Now, I can add some annotations to make the serialization nicer. I'll import JsonProperty from Json.net, and set this order to be at the very top. I want the Method property to be right below Href, and I'm going to set NullValueHandling to NullValueHandling.Ignore, so that if this is null, it'll be ignored and left out of the serialization. I'm also going to set DefaultValueHandling to Ignore.
That way, with the default value of get, it'll also be ignored. In Ion, a value of get for Method is the same thing as null. I'll need to add one more annotation called DefaultValue, which is in the ComponentModel name space. Instead of using a string here, I can refactor this to use a constant. This way we can reuse this value elsewhere in the application.
I'll handle the Relations property similarly. If it's null, I want it to be ignored. I also want to serialize this as rel, rather than Relations, in line with the Ion spec. This takes care of the properties that need to be returned to the client, but we still haven't solved the problem of generating the absolute URL from our service code. What we do have access to in our service and mapping code is the name of the route and any route parameters. This is what needs to be passed to URL.link at some point to generate the absolute URL.
We'll store these values in the link class as well, and then create a filter that calls URL.link and reads these values. So, I'm going to add two more properties, one called RouteName, and one called RouteValues. And for these, I'm going to use JsonIgnore, so that these are not serialized and sent back to the client. We'll only use these internally. To make creating a link instance really simple, let's add a static helper function that sets the default values.
I'll create a static method called To, which returns a Link, given a routeName, and some optional routeValues. This will simply return a new Link instance with the RouteName and the RouteValues that were passed in, the Method as the default, which is Get, and null Relations. Now, we can use this Link class in our control and service code. If you open up the RootController class, you'll see that I refactored the RootController slightly.
It now returns a response model called RootResponse. You can find this model in the Models folder. The RootResponse model contains two links, one for Info, and one for the Rooms route. You can find this code in the exercise files in the begin stage for this video. In the RootController, you can now take the code that was calling Url.link and replace it with code that calls Link.To. So, for the Rooms route, we can say Link.To and give it the name of the RoomsController.GetRooms, and no route parameters needed.
For the Info controllers, very simple. Link.To, the name of InfoController.GetInfo, and no route values for this one, either, so we can leave that off as well. Next, we'll create a filter that will automatically generate an absolute URL for each one of these Link instances.
- REST vs. RPC
- Using HTTP methods (aka verbs)
- Returning JSON
- Creating a new API project
- Building a root controller
- Routing to controllers with templates
- Requiring HTTPS for security
- Creating resources and data models
- Returning data and resources from a controller
- Representing links (HREFs)
- Representing collections
- Sorting and searching collections
- Creating forms
- Caching and compression
- Authentication and authorization for RESTful APIs