Skip to content
This repository has been archived by the owner on Sep 16, 2021. It is now read-only.

create a RestBundle that creates routes to any content on the fly #180

Open
lsmith77 opened this issue Dec 4, 2013 · 13 comments
Open

create a RestBundle that creates routes to any content on the fly #180

lsmith77 opened this issue Dec 4, 2013 · 13 comments

Comments

@lsmith77
Copy link
Member

lsmith77 commented Dec 4, 2013

essentially it ships a RouteProvider that can dynamically create a route for any content in the repository along with a controller that can handle all the different HTTP verbs. this might eventually also replace the JSON-LD enabled controller in CreateBundle.

this is somewhat related to symfony-cmf/content-bundle#93 however this ticket is about providing REST read support for content that is exposed via explicit routes.

maybe some inspiration can be taken from the Magnolia 5.2 REST Module:
http://documentation.magnolia-cms.com/display/DEV/Concept+REST+module

@ElectricMaxxx
Copy link
Member

I think we should go a way sonta admin (phpcr) goes for the routing. We would have the document path as an id and can work on it.
But what you really looking for is a way to have the routes available, right?
Is there a chance to cheat our RouteProvider to generate those routes too?

@dantleech
Copy link
Member

Is this addressed by: https://github.com/symfony-cmf/ResourceRestBundle ?

@lsmith77
Copy link
Member Author

well we have two things to cover here imho:

  1. a REST API for the PHPCR repository itself
  2. a REST API which is route aware (.ie similar to the ContentBundle and CreateBundle, exposes routes and their referenced content via REST)

From what I have gathered so far the ResourceRestBundle only covers 1) but not (yet) 2)

@dantleech
Copy link
Member

the Resource REST API will embed the PHPCR-ODM documents, and serializes them using the Hateoas serializer. This means that you can map _links on any serialized object.

For example:

{
     "path": "/resource/path"
     "document": {
        "_links": {
             "url": {
                 "/url/to/this/content"
             },
             "html_edit": {
                 "/admin/edit/1234"
             },
             "html_view": {
                 "/admin/view/1234"
             },
        },
        "title": "Foobar"
    "children": {
        // ...
    }
}
/**
 * @Hateaos\Relation("url", "route(object)")
 * ...
 */
class Article
{
}

@lsmith77
Copy link
Member Author

yes .. but take for example a path like /cms/routes/foo .. as a user of the API to cover 2), I do not want to have to know that this is the path /foo. In the same way I do not want to have to know that /cms/simplecms/bar is the path for /bar.

@dantleech
Copy link
Member

have you got an example of the request / response you would want?

@lsmith77
Copy link
Member Author

ContentBundle inside the Sandbox example:

$> curl http://cmf-sandbox.lo/app_dev.php/en -H Accept:application/json
{"id":"\/cms\/content\/home","title":"Homepage","body":"<h2>Welcome to the Symfony CMF Demo<\/h2>\n<p>If you see this page, it means that the <a href=\"http:\/\/cmf.symfony.com\">Symfony CMF<\/a> installation ran successfully!<\/p>\n<h2>How to proceed<\/h2>\n<p>There is a couple of bundles to look into in the vendor\/symfony-cmf\/ folder. Look at the main README but also at the individual README files of the bundles.<\/

@lsmith77
Copy link
Member Author

BTW I just checked the CreateBundle and there it seems we are currently using the actual repository paths inside the RDFa, which means there we will not need anything special:

curl 'http://cmf-sandbox.lo/app_dev.php/en/symfony-cmf/create/document//cms/content/home' -X PUT -H 'Host: cmf-sandbox.lo' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:34.0) Gecko/20100101 Firefox/34.0' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate' -H 'Content-Type: application/json; charset=UTF-8' -H 'X-Requested-With: XMLHttpRequest' -H 'Referer: http://cmf-sandbox.lo/app_dev.php/en' -H 'Cookie: lunetics_locale=en' --data '{"@subject":"</cms/content/home>","@type":"<http://schema.org/WebPage>","<http://schema.org/headline>":"Homepage","<http://schema.org/text>":"<h2>Welcome to the Symfony CMF Demo!</h2>\n\n<p>If you see this page, it means that the <a href=\"http://cmf.symfony.com\">Symfony CMF</a> installation ran successfully!</p>\n\n<h2>How to proceed</h2>\n\n<p>There is a couple of bundles to look into in the vendor/symfony-cmf/ folder. Look at the main README but also at the individual README files of the bundles.</p>\n"}'

@dantleech
Copy link
Member

ok i understand now. I wonder if it should be in the scope of the ResourceRestBundle - it would be possible to add something to retrieve the "Resource" REST response .. but would that be what we would want?

I also wonder if we should make the ResourceRestBundle simply RestBundle and increase its scope (we basically delegate most things to BazingaHateoasBundle and JMSSerializer for all the technical stuff anyway).

@lsmith77
Copy link
Member Author

Yeah, I am not sure if its within the scope or not. Depends on what it takes to implement it. Essentially the difference to me is that we have to go through the entire standard routing system and not a special end point that ensures we go through a specific controller.

What I could imagine is a listener that re-writes the Controller for specific output formats after the routing is finished.

@dantleech
Copy link
Member

It would be really easy if we just use the Hateoas serializer to serialize the _contentDocument

@ElectricMaxxx
Copy link
Member

A question would be: what about POST requests? this would mean a new content on a new route, so the RouteProvider would not be able to guess a controller as the route is unknown.

@ElectricMaxxx
Copy link
Member

(unfortunatly posted in ContentBundle issue):

I think i would have a first suggestion: RestBundle
Just started working on a first issue. By the help of the routing bundle and an own enhancer a controller given as a pure service name will get its method depending on the method. I tested it with the given methods. And yea ... i can route each method to a specific method in a dummy controller.

The ideas are:

  • create routes with method constraints
  • enhancers matching the method and add informtion to route an action
  • one enhancer for all (at least CRUD)
  • or enhancers for eauch method
  • create routes for collection endpoints without any content -> can fetch POST, PUT (move) and GET (listAction)
  • PUT/GET/DELETE can go on the given routes
  • No controller inside RestBundle
  • example implementation in the ContentBundle with a RestController equal to our ContentController
  • sonata admin extension for easy method adding
  • sonata admin extension for collection handling (like reference many fields)

Note:
there is just one test, which helped me to implement the example. There can be some stuff copied from routing-bundle (g) and there is no stuff like xsd. I will add/fix that later on. I just wanted to get feeling for that.

Edit:
Thinking about that i would name it RestRoutingBundle as it is an addon to our dynamic routing only.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants