RESTful UriTemplate Optional Paths

Topics: Web Api
Feb 4, 2011 at 7:15 AM
Edited Feb 4, 2011 at 7:19 AM

In Short: Is there some way to use ClientBase<T> to append URITemplate bits to an already defined RESTful service client endpoint address?

Let's assume there is some REST interface out there providing lots of useful(?) information about chocolate:

../chocolates/products
../chocolates/products/colors/white

To create a client for the endpoints above, I write something like this service contract:

[ServiceContract]
public interface IChocolatteClient
{
	[OperationContract, WebGet(UriTemplate="chocolatte/products")]
	XElement GetProducts();
	
	[OperationContract, WebGet(UriTemplate="chocolatte/products/colors/{color}")]
	XElement GetProducts(string color="");	
}

What I really want though, From a code perspective, is to write the two URI's as one function with an optional argument:

[ServiceContract]
public interface IChocolatteClient
{
	[OperationContract, WebGet(UriTemplate="chocolatte/products/colors/{color}")]
	XElement GetProducts(string color = "");	
}

I See the "color" argument as an optional argument, and would like to be able to simply use some simple logic in my implementation, such as:

public class ChocolatteClientRest : ClientBase<IChocolatteClient>, IChocolatteClient
{
	XElement GetProducts(string color = "")
	{
		var channel = CreateChannel();
		return channel.GetProducts(color);
	}
}

This, however, does not work, because I need some magic from the UriTemplate that can let me indicate that one bit of the URI template (namedly the "colors/{color}") needs to be conditional. Is this doable in any way?

Alternatively, is it possible to append the "colors/white" argument during runtime in some smart way?

I am assuming that "deeper down", I can probably write an interceptor, or reimplement the channel object to support dynamic URI's, but that is a messy thing to do, and if I can get away with it by using ClientBase<T>, the solution will have a much higher degree of maintainability.

In advance, thanks for reading!

 

From Norway

 

 

Feb 5, 2011 at 1:19 AM

Please don't use ClientBase<T> to access REST services.  One of the benefits of using REST over HTTP is you get to take full advantages of HTTP as a application protocol and get away from an RPC architecture.   By using ClientBase<T> you are tunneling RPC over what is supposed to be RESTful.  

The new HttpClient is really quite easy to use and you can achieve very similar results quite simply,

 

    public class ChocolatteClientRest {
        HttpClient _HttpClient = new HttpClient("http://chocolate.org/");
        Dictionary<string,string> _Bookmarks = new Dictionary<string,string>() {
                                                            {"products","chocolatte/products"},                       
                                                            {"productsbycolor","chocolatte/products/colors/{color}"}                       
                                                            };
        
        XElement GetProducts(string color = "") {
            string url;
            if (color == "") 
                    url = _Bookmarks["products"]; 
            else 
                    url = _Bookmarks["productsbycolor"].Replace("{color}", color);
            
            var response = _HttpClient.Get(url);
            
            return XElement.Load(response.Content.ContentReadStream);
        }
    }

 

Feb 7, 2011 at 6:45 AM
Edited Feb 7, 2011 at 7:10 AM

Thank you for your response, Darrel.

In my understanding, WCF was, and is designed in order to let the developers "forget" protocol. I need some more arguments as to why I should leave the comfort of WCF behind and work on a specific protocol (http in RESTful today, who knows what in the future?) .

You say that the RPC architecture in this situation is bad -  I'm not saying I disagree with you, could you give me a few reasons why?

I find it to be beneficial for our project to have a common way (across teams) of configuring services in the solution that we are writing. We serve and consume services, both RESTFul and SOAP endpoints. By adopting WCF, everyone in my team knows, or can easilly look up details on how to set up endpoints, security, message lenghts, etc, regardless of transport. Isn't that the whole point of WCF?

Using ClientBase<T>, I have the same structure in code, as does WCF in general. I admit, I would like to see a few more http options available to me, such as being able to control http-caching, custom headers, etc (i.e. in a HttpClientBase<T> implementation of a ServiceContract), but the cleaniness and "well-documentedness" of WCF far outweigh this so far.

Is there, something in the ClientBase<T> RESTful implementation that I should be aware of that makes you suggest your solution?

 

Coordinator
Feb 7, 2011 at 7:46 AM

I think Darrel's point is that HTTP is an application protocol that is based on resources and HTTP methods, not on classes and class methods. ClientBase<T> is designed around the fundamental idea that you are invoking a method on the server. When you use it you are working in a model that is protocol agnostic and thus you are not really taking advantage of HTTP and are coupling to implementation details. HttpClient however is designed entirely around HTTP, thus things like working with resources, multiple representations, hypermedia or etags are much more natural.

It's all about tradeoffs.

Feb 7, 2011 at 9:07 AM

I do remember you showing us some neat stuff, such as using exactly the same resource location to retrieve different types of data (text vs an image) simply by specifiying the http-accept type, but in my world, you were still invoking a method call; you just chose to put some of the parameters in the http header. Wouldn't this be equally achievable in WCF by use of "HttpRequestHeader" of sorts, or simply: 

[ServiceContract]
public interface IPersonServiceClient
{
	[OperationContract, WebGet(UriTemplate="people/{personId}", RequestHeader="Accept: text/xml")]
	public XElement GetPersonData(int personId);

	[OperationContract, WebGet(UriTemplate="people/{personId}", RequestHeader="Accept: image/jpeg")]
	public Object GetPersonImage(int personId);
}
The above example is just a suggestion, of course, it's not real.
The overhead given by WCF probably warrants the HttpClient object in many cases, however, I dont see this as something we as developers have to choose between;
we should be able to get that cake AND eat it too! 
Feb 7, 2011 at 12:16 PM

Digital Dias,

Using WCF in a transport agnostic way is like cake.  REST is like bacon.  Both awesome, but not together.  Pick the right one for the right occasion.

Feb 7, 2011 at 6:21 PM

Very interesting thread when it comes to distributed application development.  I'm with digitaldias because I bought into the fact that WCF is suppose to be transport agnostic.  I dove into Silverlight and WCF because Silverlight was a fully graphical interface via the web, and WCF was something that Microsoft put milllions and millions of dollars into to create service endpoints with a vast arrary of features.

Now I've heard Ron Jacobs/Microsoft, as well as Don Demsak/Tellago (Philly.Net Code Camp) both say that (proper) WCF Services is something that the market is not embracing, and that REST is the interface of choice.....  Sure REST is simple and easy, but is it really for LOB applications that demand the security and robustness required for an enterprise?  Does OData/WCF Data Services mean that professional LOB  application will leave an entire database wired to the web? (Yes i know this can be limited, but that is not what is going to happen..)

Silverlight needs to talk to services in order to retrieve data - why does WCF RIA Services has to have a custom binding in order to achieve it transport requirements?  If MS is all about applications, then why is MS not concentrating on allowing their flag ship product to create a connection with service endpoints that are secure, reliable, and feature rich with WS*.  The tcp implementation into Silverlight is a train wreck that no serious solutions architect will consider, so we are going to go with HTTP?  Really?

Come on MS - you can do better than this.  With Bob M. gone, can we please have somebody step up the plate and make the hard decisions about how to move forward on this! ScottGu where are you!

I want Silverlight, and I want proper WCF with all the features and capabilities that it has.  I realize that this has turned somewhat into a rant but either HTTP steps up to the bar, or Silverlight gets the ability to invoke web services with the capabilities it needs.  I don't really care which way, but somebody better get a direction on this, or somebody will step in and we'll all have to live the HTML saga overagain with HTML5 and browser incompatabilities.. (serious have we not learned yet that cross vendor compatability is simply not possible - SQL, Java, HTML, etc.

it's 10am, and I'm ready for drink!  argghhhh!

Feb 7, 2011 at 7:09 PM

Codputer,

You ask an excellent question.  Here are a few observations.

- You don't need to deliver an application via a web browser to take advantage of the architecture of the web.

- WCF supports transport agnostic development, but HTTP is not a transport protocol, it is an application protocol.

- REST is only a valid architecture for certain scenarios.  WCF based RPC is sometimes a better option.

- REST is definitely not easy.

- If banks can deliver bank account information to home users over the web, then it's secure enough for 99% of LOB applications

- OData/WCF Data services should never be the primary backend for a LOB application IMHO.  LOB applications may consume data from OData sources and may even do updates to it, but I do not believe that OData should be used for a LOB application backend.

- WCF RIA Services violates my last assertion.  IMHO it is just architecturally wrong.

- If you really must host your app in a browser, Silverlight should be able to exist as a completely RESTful client using HTTP.  You just need the right architecture.

- Don't let any technology vendor define your architecture.  Don't wait for MS to come up with an end-to-end technology stack.  Design your architecture as per your requirements and plug in the right technology in the right place. 

- If you think the world of HTML has been bad so far, just wait, the pain is only just beginning. 

 

 

 

 

Feb 8, 2011 at 7:06 AM
Edited Feb 8, 2011 at 7:23 AM
DarrelMiller wrote:

Digital Dias,

Using WCF in a transport agnostic way is like cake.  REST is like bacon.  Both awesome, but not together.  Pick the right one for the right occasion.

That just took the air out of me.

I thought this was a professional forum. If you can't argue your point better than that, you shouldn't be posting. I see no benefit from this kind of reply whatsoever.

Any moderator out there can just kill this thread please, I never meant for it to become this.

Coordinator
Feb 8, 2011 at 7:39 AM

@digitaldias both models are supported. Which one you choose is really a question of tradeoffs.

When you choose the contract / client model you get something that feels very much like you are invoking a class and a method hence the RPC nature. The upside is you get compile time safety, intellisence, etc. The downside is you limit yourself in terms of fully leveraging HTTP as the model makes a whole bunch of assumptions of how it uses HTTP and does eveything to shield you from the underlying application layer protocol. It also creates coupling to implementation details on the server, something that HTTP was designed specifically to avoid.

So if you if you want to take advantage of HTTP to it's fullest and yield the scalability, evolvabiltiy and simplicity benefits that the founders of HTTP wanted, you will find that model falls down quickly. If talking across multiple transports / transport independence is more important for you then those specific benefits than using client base is the right choice.

Glenn

Feb 8, 2011 at 9:24 AM
Edited Feb 8, 2011 at 1:24 PM

What I'm trying to ask is: Why should I implement httpClient over WCF? Are there performance benefits, or design benefits that outweigh the use and/or simpllicity of the WCF architecture?

(btw, Darrel: HTTP = Hyper Text TRANSFER Protocol, I hope you can forgive me for interpreting this as a transport protocol :) )

Feb 8, 2011 at 9:37 AM

Digital Dias,

 

yes, sure. There are benefits: all the system properties induced by proper use of HTTP. E.g. scalability, maximized decoupling, etc. (check the REST vs. RPC debates on the Web on this).


Since you can't do proper HTTP with WCF now, Glenn started the WCF HTTP effort (and, doh, - am I happy he did :-)

I am with Darrel, BTW: "Pick the right one for the right occasion." -- Understanding the trade offs involved when choosing connector styles is the essence of good networked system design. 


Jan 

Feb 8, 2011 at 12:43 PM

HttpClient was designed for sole purpose of interacting with distributed systems using the HTTP protocol.  WCF enables you to create an RPC based application protocol .  If you know you are going to be using HTTP, then HttpClient is going to be more efficient because you avoid the unnecessary layers of abstraction.  You also get better control because the HTTP infrastructure is not hidden from you.