Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing back multiple service uris

I have created an asp.net web api 2 controller to manage a logical asset. As usual, the post creates it and returns the uri to the asset and the delete removes it, but I have 2 puts to perform seperate actions on the asset, so my code looks like:

public class Controller : ApiController
{        
    public IHttpActionResult Post(Stuff stuff)
    {
        var id = CreateNewStuff(stuff);

        return CreatedAtRoute("DefaultApi", new { id = this.id }, id);
    }   

    [HttpPut]
    public IHttpActionResult ActionA(int id, ActionAStuff stuff)
    {    
        // Perform action A

        return Ok();
    }   

    [HttpPut]
    public IHttpActionResult ActionB(int id, ActionBStuff stuff)
    {    
        // Perform action B

        return Ok();
    }   

    public IHttpActionResult Delete(int id)
    {
        // Delete the asset

        return Ok();
    }  
}

So that the routing understands this, my routing rules are (including the default rule):

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

This works, and feels like the system neatly seperates the put code by action, and ensures the system will reject requests for actions we do not support.

The problem is that the client that creates the asset via post does not know what the put (action) uris are, in the way it does for the asset uri via the location header returned from the post. If we change the uri form in future, the clients would break as they would be manually creating uris.

What is the correct way to either return multiple servicepoint uris from the post, or just do the above better.

like image 426
John Freebs Avatar asked Dec 12 '16 14:12

John Freebs


1 Answers

Use Route for differentiating the actions. For Example:

[RoutePrefix("api/Admin")]
public class Controller : ApiController
{        
    [Route("ActionA")
    [HttpPut]
    public IHttpActionResult ActionA(int id, ActionAStuff stuff)
    {    
        // Perform action A

        return Ok();
    }   

    [Route("ActionB")
    [HttpPut]
    public IHttpActionResult ActionB(int id, ActionBStuff stuff)
    {    
        // Perform action B

        return Ok();
    }   

}

Then enable Attribute Routing in your webapiconfig.cs

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API routes
            config.MapHttpAttributeRoutes();

            // Other Web API configuration not shown.
        }
    }

finally in your client you can differentiate the put URIs like below: http(s):///api/Admin/ActionA

http(s):///api/Admin/ActionB

like image 75
Kalyan Avatar answered Sep 29 '22 11:09

Kalyan