How to make services discoverable

Topics: Web Api
Nov 22, 2011 at 3:14 PM

In normal WCF services you get a auto generated wsdl, and the services are discoverable, so you can consume the service in .NET or other frameworks and have it auto generate proxy classes. How do you setup the WCF Web API to do the same? My company will not sign off on using this framework until I have an answer to this. Thanks!

Nov 22, 2011 at 5:26 PM
Edited Nov 22, 2011 at 5:27 PM

Genereally REST APIs are supposed to be discovered "on the go" through relationships of links in data with a few documented "entry point" APIs or resources.  If you create a proxy for all the resources its more than likely that proxy will break because REST services reserve the right to change their internal URLs.

One of the core tenants of REST design is HATEOAS (Hypertext As The Engine Of Application State).. which basically means that clients aren't supposed to have a known tree of URLs and format requests to URIs themselves, but rather discover those via the data itself.  So if you request data from one of the entry point resources, included in the response will be links to other related resources and sometimes actions you can take on the data.

You could thus write a crawler application that makes a tree of the API as it stands *right now* but you cant assume that wont change (only the entry points will stay static).
Some people have decided to offer WADL resources of their REST services, but many think this is a bad idea (because of the points mentioned above).

This is for most people the hardest thing to grasp about REST, and its very common for people to start doing REST services while still using RPC methods.

Nov 22, 2011 at 6:21 PM

Thanks for the response. This is hard to grasp, as you're talking about urls changing in the REST services, which would break any clients that consume those calls, just as easily within REST as in a .NET client using proxy classes... Why would REST APIs reserve the right to break calls that clients are making?

Nov 22, 2011 at 6:24 PM

If you're consuming a service, you are going to consume a specific url that has the data you need. You're not going to first hit a main url that says go to this service url, then hit that service url, which says go to this url to call this method. It just doesn't make sense what you're saying...

Coordinator
Nov 22, 2011 at 6:42 PM
Edited Nov 24, 2011 at 5:19 AM
He is talking about hypertext / hypermedia driven systems. It is actually what the web was built for. It is a paradigm shift, but totally doable. Web pages use this approach today. When you navigate a website like yahoo.com, you start a root uri for the site. After that all of your interactions are via the server providing links. You don't memorize yahoo's uri namespace ;-) that means you get great evolvability. The server can change links and the client is not broken.

That works for browsers. The shift comes when you move outside of a browser. You do things a bit differently, but same rules apply.

http://codebetter.com/glennblock/2011/05/09/hypermedia-and-forms/

One good resource is the new REST IN PRACTICE book. Another is Mike Amundsen's forthcoming book on hypermedia systems with HTML5. But alot of that content you can find on his blog.

I would really recommend checking it out (amundsen.com)

Sent from my Windows Phone

From: jtoth55
Sent: 11/22/2011 11:25 AM
To: Glenn Block
Subject: Re: How to make services discoverable [wcf:280427]

From: jtoth55

If you're consuming a service, you are going to consume a specific url that has the data you need. You're not going to first hit a main url that says go to this service url, then hit that service url, which says go to this url to call this method. It just doesn't make sense what you're saying...

Nov 22, 2011 at 8:05 PM

Yes this is totally doable, but takes time to adapt to.  My biggest gripe with hypermedia driven services is the amount of HTTP calls you are making, it goes totally against the "chunky not chatty calls" mantra we were taught when learning RPC/SOAP methods.

However most of the HTTP calls are very lightweight and send rather few bytes across the wire, and with a proper caching strategy things start to even out.  Just remember this is the way the web is built, and that works :)  Its not uncommon today to visit a webpage that makes tens if not close to a hundred web requests loading images, scripts and so on.
In fact it often helps me to think of a REST service as a website with json documents, and methods to modify those documents.

Nov 22, 2011 at 8:19 PM

Thanks guys for the input!

Nov 25, 2011 at 6:49 AM

Hi,

I get the hypermedia driven paradigm and like @SiggiG also think see a REST service as a service that serves representations of data which may refer (via hypermedia links) to other data/media resources.

However, and here is my dilemma, for an HTML5/JavaScript client all is fine because JavaScript supports or rather understands untyped data (json).  So if you GET a resource with links to further resources that have some structure it is fine/easy to consume those in an HTML5/JavaScript client - its natural to the language.

What does one do in the case of a complex (i.e. many hundreds of entities) WPF/Java client that relies on concrete types (entities) to represent the resources you get from your REST service.  It seems to me that typed languages are not a good fit for this type of system unless you go to great lengths and discomfort to create and work with property-bag like entities.

Any comments, suggestions would be much appreciated!?

Coordinator
Nov 25, 2011 at 8:35 PM
You can get a similar loosely typed experience on .net by using the dynamic JasonValue support.

Sent from my Windows Phone

From: AnotherWay
Sent: 11/24/2011 11:50 PM
To: Daniel Roth
Subject: Re: How to make services discoverable [wcf:280427]

From: AnotherWay

Hi,

I get the hypermedia driven paradigm and like @SiggiG also think see a REST service as a service that serves representations of data which may refer (via hypermedia links) to other data/media resources.

However, and here is my dilemma, for an HTML5/JavaScript client all is fine because JavaScript supports or rather understands untyped data (json). So if you GET a resource with links to further resources that have some structure it is fine/easy to consume those in an HTML5/JavaScript client - its natural to the language.

What does one do in the case of a complex (i.e. many hundreds of entities) WPF/Java client that relies on concrete types (entities) to represent the resources you get from your REST service. It seems to me that typed languages are not a good fit for this type of system unless you go to great lengths and discomfort to create and work with property-bag like entities.

Any comments, suggestions would be much appreciated!?

Nov 28, 2011 at 4:32 AM

Thanks Dan,

I did see the JasonValue support and have a few (noobish) questions:

Does JasonValue work with XML - i.e. can an xml message be deserialized into a JasonValue?
Is JasonValue used in LOB WPF applications and how well does it play with binding?
Because it is much less typed, does this imply more assumptions by the client developer as to what member types are (i.e. does it require more domain knowledge on the client)?

In other words what strategy are people out there adopting for the dynamic nature of REST in respect of the proliferation of message like 'entities' that are spawned for RESTful interaction between client and server?  I can accept that creating static (C# POCO or other) entities for the Data Model is not that different from say an EF based system, but do people agree that REST does introduce a much more dynamic paradigm that moves away from your typical static Entity based systems?

Regards.

Nov 28, 2011 at 12:07 PM

I don't agree that REST data should be considered more dynamic than other ways of creating web services.
While resources can move around and you do need to follow links/relations, a good REST service should stay backward compatible.  This means the data isn't really dynamic, but can potentially move around, and get stuff added.

Many people type their resources using custom MIME types ("application/vnd.companyName.projectResource+json"), and when they need to break compatibility they offer multiple versions of the same resource.  For example the same url can offer both "application/vnd.companyName.projectResource+json" and "application/vnd.companyName.projectResource-v2+json".

I think it's still perfectly valid to use data classes in your projects, for both client and server.  Not every client has the same use cases, so you often need to do multiple service calls to construct the data (type) you need.  And data classes are useful in services to keep compatibility and offer versioning (Resource.cs and ResourceV2.cs).

As for using xml with JsonValue.. if you really want to go down the dynamic road, you can always just use dynamic types introduced with C# 4.0.

Coordinator
Nov 28, 2011 at 5:45 PM

JsonValue is for JSON data only.

Unfortunately, JsonValue does not currently work directly with data binding. You can do data binding manually using its Changed family of events.

If supporting data binding directly on JsonValue is important to you please file an issue in Issue Tracker so that the community can vote on it.

Daniel Roth

Nov 29, 2011 at 5:08 AM

Hi,

SiggiG - correct - dynamic is the wrong word, more specifically I see REST (if done properly - i.e. no RPC-URL tunnelling etc.) as prolific in terms of additional application 'entities' outside of the core business data model. To me REST seems to required a large number of resources used to represent state during interactions between client and server when dealing with a real world LOB system. For instance we have a large medical system that has roughly upwards 180 tables for the data model.  Apart from simplistic single entity CRUD operations, there seems to be many additional application level entities representing workitems, transactions, coordinated updates to related data model entities, etc.  Its these non-data model representations that I refer to.  It would be great to have an easy mechanism to support this kind of entity without bloating the data model.  Perhaps a JsonValue type that plays well with WPF/Metro etc.  In other words as JSON is to the HTML5/JavaScript world we need an 'xxx' for the WPF/Metro C# world.

Dan - Thanks, I did see JXmlToJsonValueConverter which gave me some hope... binding is an issue.

Regards