0

I want to create a REStful web service.

This service returns "Meetings" for a certain

day, week or months.

I would create 3 Get methods which takes date values determined by the API user.

GetMeetingsByDay(currentDate)
GetMeetingsByWeek(startDate,endDate)
GetMeetingsByMonth(startDate,endDate)

Having 3 Get methods I could not access the API anymore just via http-method type 'GET' like:

// GET: api/meetings/date

because there will be multiple GET...

I could merge the ByWeek and ByMonth methods and do this instead:

GetMeetings(startDate,endDate);

How would you make this service RESTful?

leppie
  • 115,091
  • 17
  • 196
  • 297
Elisabeth
  • 20,496
  • 52
  • 200
  • 321

4 Answers4

2

I wouldn't think of it in terms of the method names - I'd think of it in terms of the URLs to start with:

/api/meetings?date=...
/api/meetings?startDate=...&endDate=...

Think of it as a collection of meetings, and the query parameters are just that - query parameters. I would expect any value after the meetings element in the URL to be a meeting ID - for example, your GetMeetings method might return a meeting with an ID of foobar which I'd then expect to be able to fetch later with

/api/meetings/foobar

That suggests to me that you shouldn't have date as part of the URL path at all.

In terms of implementation, I don't know enough about WebAPI routing to know whether you could implement that with two methods of:

[HttpGet]
[Route("api/meetings")]
public ... GetMeetings([FromUri] DateTime startDate, [FromUri] DateTime endDate)

[HttpGet]
[Route("api/meetings")]
public ... GetMeetings([FromUri] DateTime date)

... or whether you need to a single method with optional parameters:

[HttpGet]
[Route("api/meetings")]
public ... GetMeetings(
    [FromUri] DateTime? date = null,
    [FromUri] DateTime? startDate = null,
    [FromUri] DateTime? endDate = null)

In the latter case you'd need to then validate that the set of arguments provided was valid.

(As noted in comments, you may not need the Route here at all.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • But the Route Attribute is only needed afair -please correct me - when I do not name my methods just GET? Just the the HTTP Verb. – Elisabeth May 25 '15 at 10:18
  • @Elisa: Sorry, I can't parse your comment. If you find it works without the `Route` attribute, that's great - but I don't think it really affects the answer much. – Jon Skeet May 25 '15 at 10:20
  • there will be no GetMeetings() or GetMeetings(id) because I fetch only via date-/range – Elisabeth May 25 '15 at 10:26
  • @Elisa: So don't implement those yet - although I'd *encourage* you to implement `GetMeeting(id)` just on general principle. Again, I don't see how that really affects the answer, in terms of what you're trying to achieve... – Jon Skeet May 25 '15 at 10:26
  • another alternative would be: public HttpResponseMessage Get([FromUri] MeetingsRequest request) a complex object. – Elisabeth May 25 '15 at 10:50
  • @Elisa: Sure, that would work. But definitely think about the URL structure before the implementation. – Jon Skeet May 25 '15 at 10:58
1

Web API 2 supports a new type of routing, called attribute routing.

This is the scenario where you need to use attribute routing.

eg:

 [Route("customers/{customerId}/orders")]
 public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }

One advantage of convention-based routing is that templates are defined in a single place, and the routing rules are applied consistently across all controllers. Unfortunately, convention-based routing makes it hard to support certain URI patterns that are common in RESTful APIs.

Read more here :

From a previous good answer (source):

If you have a multiple Get actions that have a single primitive argument of the same type, ASP.NET Web API will look at the name of the argument to resolve which overloaded action to call.

For example, if you have two actions:

GetProductByName(string name) 
GetProductByCategory(string category) 

your http client can call as :

api/products?name=hammer 
api/products?category=toys

and the routing engine will call the correct action.

The SO question, How does ASP.NET Web.api handle two methods with names starting with GET? can give you some more knowledge as it had been well answered.

EDIT :

I could merge the ByWeek and ByMonth methods and do this instead:

GetMeetings(startDate,endDate);

Definitely I would encourage this if you don't have any specific logic going into the GetMeetingsbyWeek and GetMeetingsbyMonth, like it merely fetches a list from database between the specified date range.

Community
  • 1
  • 1
Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112
0

Look at Web API routing - http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

Otherwise, you could use just a querystring - like api/meetings/date?currentDate=x&startDate=x&endDate=x

whoah
  • 4,363
  • 10
  • 51
  • 81
0

For creating a WebApi Controller with multiple GET requests, You need to specify the route as follows:

routeTemplate:api/{Controller}/{action}/{param}

This should solve your problem.

Amit Kumar Ghosh
  • 3,618
  • 1
  • 20
  • 24