HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

A Get method for an API, with three modes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
threemethodwithgetforapimodes

Problem

Is this good way to create a get API method with different service methods?
Based on the scope parameter, it decides what service method in the API to call.

Enum:

enum scopeValue
    {
          None,
          GetAll, 
          GetWithDetails 
    };


API:

public class WorkItemController : BaseController
    {
        private IWorkItemService workItemService;

        public WorkItemController(IWorkItemService workItemService)
        {
            this.workItemService = workItemService;
        }

        [HttpGet]
        public async Task> Get(int id, string scope = "None")
        {
            scopeValue choice;

            Enum.TryParse(scope, out choice);

            if (choice == scopeValue.None)
            {
                return await workItemService.Get(id);
            }
            else if (choice == scopeValue.GetAll)
            {
                return await workItemService.GetAll();
            }
            else if (choice == scopeValue.GetWithDetails)
            {
                return await workItemService.GetAllWithDetails();
            }
        }
    }

Solution

Let's think about what your possible URIs would look like.

http://example.com/WorkItem?id=5
http://example.com/WorkItem?id=5&scope=GetAll


That's not how I'd expect the API to work. Typically, calling the resource without an id will return all of them.

// returns all work items
http://example.com/WorkItem

// returns work item by id
http://example.com/WorkItem/5


And then, to get the details for an item, we add an action to the end of the URI.

// returns details for specified item
http://example.com/WorkItem/details/5


To get the last part, you'll need to wire up a custom route, but it's not that difficult to do. You can then overload the Get methods to implement this. It's a much cleaner API to work with and, honestly, results in a much cleaner & maintainable controller.

I take it back, you won't need a custom route. MVC comes "out of the box" with a {controller}/{action}/{id} route, so for the Detail route, all you need to do is create the proper method.

[HttpGet]
public async Task> Details()


And

[HttpGet]
public async Task> Details(int id)


Will give you routes that look like this.

http://example.com/WorkItem/Details
http://example.com/WorkItem/Details/5

Code Snippets

http://example.com/WorkItem?id=5
http://example.com/WorkItem?id=5&scope=GetAll
// returns all work items
http://example.com/WorkItem

// returns work item by id
http://example.com/WorkItem/5
// returns details for specified item
http://example.com/WorkItem/details/5
[HttpGet]
public async Task<IEnumerable<WorkItemDto>> Details()
[HttpGet]
public async Task<IEnumerable<WorkItemDto>> Details(int id)

Context

StackExchange Code Review Q#111997, answer score: 4

Revisions (0)

No revisions yet.