2
votes

In WCF REST i could define a strict URL template.

In ASP.NET MVC Web API 4 I have a problem.

I registered the route as normal:

 routes.MapHttpRoute(
                 name: "DefaultApi",
                 routeTemplate: "api/{controller}/{id}",
                 defaults: new { id = RouteParameter.Optional }
             );

My controller have this method:

// POST /api/documents
public HttpResponseMessage<Document> Post(Document document) 
{...}

If i send a POST-request with this URL "http://servername.com:53835/api/Documents/1337" (The parameter "1337" should not be there), it calls the Post(Document document) method. But i want, that the framework shows an error in this case. (e.g. "No API-Call found for this request").

With REST WCF i could configure this strictly... I am not so enthusiastic about this "convention over configuration"...

And how can I do more complexe URL templates?

  • I want something like this:

An API for a GET-Request with this URL-template: "http://servername.com:53835/api/Documents/1337" to get a specific document-object (contains metadata like creation date, creator etc ...).

Another GET-Request should retrieve the file itself (as a stream), with this URL: http://servername.com:53835/api/Documents/1337/File

How can i define this difference? The GET-Method for getting the document-object looks like this:

// GET /api/documents/5
public HttpResponseMessage<Document> Get(int id)
{...}

How can i define a seperate method with the same parameters (in this case "id")? Do I have to configure the URL template with method attributes like in WCF REST-Projects?

I can edit the routing for the {action} placeholder like this:

routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{mandant}/{controller}/{id}/{action}",
                defaults: new { mandant = "profile", id = RouteParameter.Optional, action = RouteParameter .Optional}
            );

And then I can use the method attributes [ActionName("File")] and [AcceptVerbs("GET")] lie this:

[ActionName("File")]
[AcceptVerbs("GET")]
public HttpResponseMessage FileDownload(int id)

Then i can call: "http://servername.com:53835/api/Documents/1337/File" to get the file. But what if I want more of these "actions"?

  • An complexer use case would be an URL with repetitive parts. Something like: (in this case i have some item characteristic. The number this characteristics should be variable)

http://servername.com:53835/api/Documents/characteristic_1/characteristic_2/characteristic_3 http://servername.com:53835/api/Documents/characteristic_1/characteristic_2

The part with the characteristics should be dynamic/variable.

1

1 Answers

0
votes

I have play around with this as well and I found out that this approach may cause undesired results in many cases and somehow makes your API difficult to use. What work best for me is to have just one input parameter for my API method which is the ID and pass all other variables using URL-parameters.

In order to avoid DRY-ing stuff, you could consider writing a ActionFilter or so.