I'm doing some research on how to implement hypermedia for a particular resource, but can't find a real implementation example, just abstractions...
You know, in various articles, the guy create a method like:
public List<Link> CreateLinks(int id)
{
...//Here the guy put these three dots, whyyyyyyyyyy?
}
What I have so far:
public Appointment Post(Appointment appointment)
{
//for sake of simplicity, just returning same appointment
appointment = new Appointment{
Date = DateTime.Now,
Doctor = "Dr. Who",
Slot = 1234,
HyperMedia = new List<HyperMedia>
{
new HyperMedia{ Href = "/slot/1234", Rel = "delete" },
new HyperMedia{ Href = "/slot/1234", Rel = "put" },
}
};
return appointment;
}
And the Appointment class:
public class Appointment
{
[JsonProperty("doctor")]
public string Doctor { get; set; }
[JsonProperty("slot")]
public int Slot { get; set; }
[JsonProperty("date")]
public DateTime Date { get; set; }
[JsonProperty("links")]
public List<HyperMedia> HyperMedia { get; set; }
}
public class HyperMedia
{
[JsonProperty("rel")]
public string Rel { get; set; }
[JsonProperty("href")]
public string Href { get; set; }
}
Is there a proper way to that? I mean, without hard coding the links? How to create them dynamically for a given type, i.e. Appointment class?
I'm using c# Webapi, not c# MVC.
For adding routes dynamically to the HyperMedia collection you can make use of route naming:
Define your route with a specific name (for example for deletion):
[Route("{id:int}", Name = "AppointmentDeletion")]
public IHttpActionResult Delete(int slot)
{
//your code
}
Use it by UrlHelper.Link method:
public Appointment Post(Appointment appointment)
{
appointment = new Appointment
{
HyperMedia = new List<HyperMedia>
{
new HyperMedia
{
Href = Url.Link("AppointmentDeletion", new { slot = 1234 }),
Rel = "delete"
}
}
return appointment;
};
It is also possible to add links dynamically to a result object without declaring the HyperMedia property for every class:
Define a class without links:
public class Appointment
{
[JsonProperty("doctor")]
public string Doctor { get; set; }
[JsonProperty("slot")]
public int Slot { get; set; }
[JsonProperty("date")]
public DateTime Date { get; set; }
}
Define an extension method:
public static class LinkExtensions
{
public static dynamic AddLinks<T>(this T content, params object[] links)
{
IDictionary<string, object> result = new ExpandoObject();
typeof (T)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.ToList()
.ForEach(_ => result[_.Name.ToLower()] = _.GetValue(content));
result["links"] = links;
return result;
}
}
Use it:
public IHttpActionResult Post(Appointment appointment)
{
return Ok(appointment.AddLinks(new HyperMedia
{
Href = Url.Link("AppointmentDeletion", new { slot = 1234 }),
Rel = "delete"
}));
}