I have a typical API with some CRUD operations. I typically need to get certain objects, based on different parameters.
One way to do it would be to have methods like:
GetProjectsByCustomerId(int customerId);
GetProjectsBySigneeId(int signeeId);
However, in my service layer (ProjectService in this case) I usually use a method such as the following where ProjectSpecification typically has quite a lot of fields and even lists:
public IEnumerable<Project> GetBySpecification(ProjectSpecification projectSpecification)
That means, in my dream world I would like to have endpoints such as:
/api/projects(empty specification, return full list)/api/projects?customerid=2(gets projects for customer with id 2)/api/projects?signeeid=2,3(get projects with signee id 2 and 3)
My question is - how is this done
My first attempt was adding this in my ProjectController (calling my ProjectService):
public class ProjectsController : ApiController
{
public IEnumerable<Project> GetProjects(ProjectSpecification projectSpecification)
{
var projects = _projectService.GetBySpecification(projectSpecification);
return projects;
}
}
But lets say I open this URL:
/api/Projects?CustomerId=2
This is not parsed into a ProjectSpecification viewmodel. However, if I change my controller signature to:
public IEnumerable<Project> GetProjects(int customerid) { }
It would work, because it's a simple type.
I could of course build some parameter-hell, but I guess there is something super obvious MVC magic I am missing - probably in the routing? :-)
ProjectSpecificationas part of the example. Also look into theFromUriattribute on the parameterProjectSpecificationclass would work fine, but you may need to build a custom model binder (not hard at all). Alternatively you may want to look at OData which pretty much does this for you anyway.[FromUri]should be simple enough for this scenario.