Proposal: Use a single [WebMethod] Attribute instead [WebGet], [WebInvoke]

Topics: Web Api
May 15, 2011 at 11:54 AM

There are two different Attributes to annotate operations to be web methods, namely WebGet and WebInvoke.

Maybe it´s because it should be clear to the programer, if he offers some safe GET method or some other. Or Maybe it´s because different properties are bound to each attribute.

But i think, there are some drawbacks with this:

  • What if i want to support HEAD and OPTIONS. Right now, i could use the WebInvoke attribute, because i can set the attribute property method. But this two verbs are also safe: i do not really INVOKE something, i want to GET something - the metadata (http header)
  • WebGet and WebInvoke uses properties which are in fact inconsistent with the current Web Api features like Content negotiating (like ResponseFormat = {XML, JSON})
Therefore i propose using a single [WebMethod] Attribute for annotation web operations. Or [WebOperationContract] which would be analogous to [OperationContract] from WCF.
[WebOperationContract(Method = "GET", UriTemplate = "{id}")]
public Contact Get(int id)
{
...
}
What do you think?
May 15, 2011 at 6:52 PM
Maybe [HttpMethod] ? As this would be aligned with the Web HTTP programming model?
May 18, 2011 at 5:48 PM

I think that [WebMethod] is slightly better, because it´s the Web Api :-) But the naming is not that important. My proposal is about a coherent design of the attributes.

May 18, 2011 at 6:25 PM
+1 for WebMethod
May 18, 2011 at 6:33 PM

+1 for a single attribute. I prefer [HttpOperation]

a) "operation" is the WCF term

b) "Http" is the prefix used on WCF Web API

c) There is already a HttpOperationDescription with the operation's description

 

 

Coordinator
May 18, 2011 at 6:47 PM
I have in a proposal for WebGet, WebPut, WebPost and WebDelete attributes. WebGet already exists but the proposal would be a new ctor that only accepts a UriTemplate. Also it would be to not require you to set UriTemplate to empty and for it just to work. As that is a red bits change (adding the ctor / default) it will take time for us to get that in.

We are looking at removing the coupling to attributes altogether and providing an alternative mechanism for supporting either custom attributes / conventions or your own config like via a fluent API.


>
Coordinator
May 18, 2011 at 6:51 PM
Single attribute is there today, just use WebInvoke for everything, and ignore the name.

The attributes I was suggesting mean less verbose / magic strings.


>
May 18, 2011 at 6:57 PM
99% of what WebInvokeAttribute exposes does not apply (or may cause weird side effects?) to Web API.

It only adds confusion to any newcomer to the WCF Web API.
May 18, 2011 at 10:15 PM
gblock wrote:
I have in a proposal for WebGet, WebPut, WebPost and WebDelete attributes. WebGet already exists but the proposal would be a new ctor that only accepts a UriTemplate. Also it would be to not require you to set UriTemplate to empty and for it just to work. As that is a red bits change (adding the ctor / default) it will take time for us to get that in.

We are looking at removing the coupling to attributes altogether and providing an alternative mechanism for supporting either custom attributes / conventions or your own config like via a fluent API.


>


Ideally, it would be great to get rid of the attributes altogether.  If that's not feasible, I like the separation of Web[Get|Put|Post|Delete].

May 19, 2011 at 7:16 AM
Edited May 19, 2011 at 7:09 PM

Introducing an attribute for every HTTP Method is not a good idea!

What if i want to use other methods, e.g. the one defined by WebDav. In terms of REST this is not constrained, though you risking that lesser intermediates and clients can interact with the resource. Another example: What about the PATCH method [1]? Some say, there has to be a way to do a partial update of a resource...

In Terms of HTTP there only one difference between the operations afaik: Do i embed an entity body into the HTTP Message or leave it alone (e.g. GET,DELETE).

[1] http://tools.ietf.org/html/rfc5789

May 19, 2011 at 5:52 PM

I like the idea of an HttpMethodAttribute with boolean properties for each HTTP method.

Sep 15, 2011 at 2:31 PM

I'll vote this up in the Issue Tracker but think that a single HttpMethodAttribute with an enumerated list of verbs is the way to go. (Actually, use the existing HttpMethod class that returns strings so the attribute can be easily extended for use with other methods.)  The following would do the trick:

public class HttpMethodAttribute : Attribute
{
    public HttpMethodAttribute();
    public HttpMethodAttribute(String method);
    public HttpMethodAttribute(HttpMethod method);

    public string Method { get; set; }
    public string UriTemplate { get; set; }
}