In the Google Summer of Code Project "TYPO3 Flow meets Ember.js" we are trying to make the server-side framework TYPO3 Flow and the client-side framework Ember.js (using Ember Data as the persistence layer) work together easily through conventions and a powerful scaffolding mechanism. You can visit our website to see a more detailed concept.
Please refer to the overview gist that gives a brief overview of how things should work together.
We are facing a decision how we want to logically organize the server-side controllers responsible for handling the REST API requests. There are two direction:
- Generated controllers: One controller for each model that handles the requests for the specific model.
- Automagical controller: One controller that handles all requests for all models.
- Every provided part of REST API is represented in a separate controller file => It is very clear, which controllers/models are available and where they are located.
- Can easily add additional application specific methods to the API (eg. /last_posts)
- Will lead to many files containing the very same content.
- Need to configure routes for every controller/model. This will result in a huge Routes.yaml file that is difficult to manage.
- Seems to play nice with the idea of a conventional API => same API for every model
- Just one controller file for the whole REST API needed.
- Only need to configure the routes once.
- It is more difficult to understand which routes/models are available. (Could be tackled by providing an auto-generated API description)
- Can add additional application specific methods to the API (eg. /last_posts), but methods for different models need to be mixed together in a single controller file.
For each model the following code sample would be needed to provide Embers RESTAdapter methods. The controller inherits the needed standard functionality from a controller provided by our package.
<?php
namespace Mmitasch\Blog\Controller;
use TYPO3\Flow\Annotations as Flow;
/**
* This REST controller is made for handling ember-data DS.RESTAdapter calls for post models.
*
* @Flow\Scope("singleton")
*/
class PostController extends Radmiraal\Emberjs\Controller\RestController {
}
?>
For each model the following needs to be configured in Routes.yaml. The put, post, delete, option configuration are omitted for simplification purposes. Thus, an actual configuration would be 6 instead of the shown 2 configuration blocks.
-
name: 'REST API GET all posts'
uriPattern: 'rest/posts'
defaults:
'@package': 'Radmiraal.Emberjs'
'@controller': 'Post'
'@action': 'list'
'@format': 'json'
httpMethods: ['GET']
-
name: 'REST API GET post by Identifier'
uriPattern: 'rest/posts/{modelid}'
defaults:
'@package': 'Radmiraal.Emberjs'
'@controller': 'Post'
'@action': 'show'
'@format': 'json'
httpMethods: ['GET']
# put, post, delete, option configuration omitted for simplification purposes
The following code sample would be needed once to provide Ember's RESTAdapter methods for all models. The controller inherits the needed standard functionality from a controller provided by our package.
<?php
namespace Mmitasch\Blog\Controller;
use TYPO3\Flow\Annotations as Flow;
/**
* This REST controller is made for handling ember-data DS.RESTAdapter calls for ALL models.
*
* @Flow\Scope("singleton")
*/
class RestController extends Radmiraal\Emberjs\Controller\RestController {
}
?>
The following needs to be configured once in Routes.yaml. The put, post, delete, option configuration are omitted for simplification purposes. Thus, an actual configuration would be 6 instead of the shown 2 configuration blocks.
-
name: 'REST API GET all posts'
uriPattern: 'rest/{modelName}' # notice the dynamic route segment here
defaults:
'@package': 'Radmiraal.Emberjs'
'@controller': 'Rest'
'@action': 'list'
'@format': 'json'
httpMethods: ['GET']
routeParts:
'modelName':
handler: 'Radmiraal\Emberjs\Routing\ModelNameRoutePart'
-
name: 'REST API GET post by Identifier'
uriPattern: 'rest/{modelName}/{modelid}' # notice the dynamic route segments here
defaults:
'@package': 'Radmiraal.Emberjs'
'@controller': 'Rest'
'@action': 'show'
'@format': 'json'
httpMethods: ['GET']
routeParts:
'modelName':
handler: 'Radmiraal\Emberjs\Routing\ModelNameRoutePart'
# put, post, delete, option configuration ommited for simplification purposes
We tend to find the automagical controller solution more suited for a conventional API and much more concise. What do you think?
I see your problem here...
Personally i really like the generated controller way.
It's the Flow way, it's closer to the idea of MVC and really more flexible.
In some projects there is always an additional thing to do bevor a model is created or updated, which could not be done in the Ember logic. To handle this generated controller seem more convenient.
To prevent floating the Routes.yaml you could use nested subroutes.
Otherwise, the automagical controller is the logical result for the basic idea use TYPO3 Flow only as the RESTful backend for the Ember-App.
Still +1 for generated controller.