Monday, December 16, 2013

In ServiceStack routing, be wary of using too much inheritance in the name of the DRY principal.

The following is bad as any attempt to reach the PUT implementation will just go to the POST implementation. This is one of the pain points of inheriting everything from a class that also designates a route while only differentiating the route by way of a verb and not a signature too. It is a quirk of ServiceStack it seems. The GET route may still be reached, perhaps because the shape of the JSON that is handed to it differs from that of PUT and POST implementations. I don't really know. I’ve not really used ServiceStack before today. It does seem that the abstraction here in the name of the DRY (don't repeat yourself) principle won't fly.

[Route("/widgets", "POST")]
[Authenticate]
public class WidgetCreate : WidgetUpdate
{
}
 
[Route("/widgets/{id}", "PUT")]
[Authenticate]
public class WidgetUpdate : Widget
{
   public string Foo { get; set; }
   public int Bar { get; set; }
   public DateTime Baz { get; set; }
   public bool Qux { get; set; }
}
 
[Route("/widgets/{id}", "GET")]
[Authenticate]
public class Widget
{
   public int? Id { get; set; }
}

 
 

If the POST class inherits from the PUT class, the PUT class is walled off from accessibility in circumstances where there is not enough differentiation! It is best to repeat yourself like so:

[Route("/widgets", "POST")]
[Authenticate]
public class WidgetCreate : Widget
{
   public string Foo { get; set; }
   public int Bar { get; set; }
   public DateTime Baz { get; set; }
   public bool Qux { get; set; }
}
 
[Route("/widgets/{id}", "PUT")]
[Authenticate]
public class WidgetUpdate : Widget
{
   public string Foo { get; set; }
   public int Bar { get; set; }
   public DateTime Baz { get; set; }
   public bool Qux { get; set; }
}
 
[Route("/widgets/{id}", "GET")]
[Authenticate]
public class Widget
{
   public int? Id { get; set; }
}

No comments:

Post a Comment