RESTful Web Services in .NET (Part 1)
A couple of years ago I tossed together a RESTful IHttpHandlerFactory for .NET. It wasn’t amazing, but it was being used long before Microsoft et all decided to create there own. Instead of extending Page you extended RestService and implemented whatever methods you wanted.
public interface IRestService
{
void Head(RestEventArgs args);
object Get(RestEventArgs args);
object Put(RestEventArgs args);
object Post(RestEventArgs args);
}
As you can probably guess the request’s HTTP Method was transformed into the function name and executed accordingly. If the method wasn’t “known” we would then use reflection to find the method for execution. Not to fansy as you can see, but it worked.
If a request was made for http://localhost/app/users.r the IHttpHandler factory would load users.r and it would tell us what class you assigned to it (much like @Page CodeBehind/Inherits in .aspx). From there we would instantiate the class and call the appropriate method. Whatever you returned would be marshalled for wire transfer based on it’s type.
class User : IXmlSerializable
{
/* ... */
}
public class UserService : RestService
{
public object Get(RestEventArgs args);
{
return new User(5, "Matthew", "Metnetsky");
}
}
}
Calling http://localhost/app/users.r would execute UserService::Get(..) which would return a User instance. The results are then inspected for a few different interfaces like IXmlSerializable, IJsonSerializable (one of ours), etc. Based on what is supported by the Type, we then check if the requester supports it by interogating their “Accepts” header. This way each requester can receive what they understand how to handle (for instance – don’t send JSON to AS3). The system really worked well, and it’s simplicity made it damn fast.
Like all frameworks however, once it was actually in use we were able to see the pitfalls and issues. Take a look at the following URLs:
- http://localhost/app/users.r
- http://localhost/app/users.r/1
- http://localhost/app/users.r/matthew
In order to handle all of the urls above the Get(RestEventArgs) method turned into one big switch/if/else conditional. Some people made it prettier than others, but the result was the same. So about 14 months ago we upgraded our framework – check back soon to see how we did it, and why I’m bringing it up now.
Leave a Reply
You must be logged in to post a comment.