redstone-dart / redstone

A metadata driven microframework for Dart.
http://redstone-dart.github.io/redstone
MIT License
342 stars 42 forks source link

Groups - REST style #12

Closed akofoed closed 10 years ago

akofoed commented 10 years ago

Thanks for this great framework. Just getting started using it.

This is a feature request.

I like the Jersey inspired groups annotation and I want to create a class that holds all the methods for a particular rest endpoint. But I cannot seem to get the following to work:

Collection: GET /users. (eg. json (/users.json) One user: GET /users/1.

If I put @app.Group("/users") on the class, then Redstone does not let me use @app.Route(".json") on a method inside the class.

I try to follow these principals: http://www.restapitutorial.com/lessons/httpmethods.html

Would that be possible? Thanks again and kind regards Anders Dam Kofoed

luizmineo commented 10 years ago

Yes, I think we can make Redstone more compatible with those principals. Thanks for pointing me this out.

digitalfiz commented 10 years ago

Here is an example of a possible implimentation:

@app.Group('/api/collection')
class MainController {

  @app.Route(methods: const [app.GET, app.POST])
  all() {
    // Get all from a collection
  }

  @app.Route('/:id', methods: const [app.GET, app.PUT]) 
  one(int id) {
    // Get one
  }

}

Notice how on the all route I don't pass in a string for the path. Maybe it could default to whatever the group route is.

akofoed commented 10 years ago

I disagree. I like having the route String there - so that one can see explicitly what it does. Also, you would not be able to do "GET collection.json", "GET collection.xml" or "GET collection" (without extention). I think that should be up to the user to decide that.

But having the Group annotation is awesome.

luizmineo commented 10 years ago

I added a new @DefaultRoute annotation, which can be used in methods that must be bound to the URL of its group. Example:

@app.Group("/group")
class Group {
  //GET requests to /group
  @app.DefaultRoute()
  defaultRoute() => "default_route";

  //GET requests to /group.json
  @app.DefaultRoute(pathSuffix: ".json")
  defaultRouteJson() => "default_route_json";

  //POST requests to /group
  @app.DefaultRoute(methods: const[app.POST])
  defaultRoutePost() => "default_route_post";

  //GET requests to /group/service
  @app.Route("service")
  service() => "service";
}

Also, it's now possible to define multiple routes to the same path, with different HTTP methods.

These changes are already available on the v0.5 branch. Please, let me know if you have any problem.

digitalfiz commented 10 years ago

Awesome solution @luizmineo Trying it later tonight :dart:

akofoed commented 10 years ago

Hi @luizmineo

Wow, this is awesome. Just implemented it in my project and it works perfectly.

Also, the createStaticHandler for the static stuff works as expected.

Thanks.

/Anders