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.
This document gives a short introduction of:
- how domain models look like in Flow and Ember Data,
- how the REST JSON API is expected to look like (to follow Ember Data conventions),
- for which models REST APIs are provided and how.
The following diagram gives an overview of what components a Ember/Flow app would consist of. Components that are generated (scaffolded) are illustrated with a green background. Components that are provided through our Flow package or are part of ember-data are illustrated with a blue background.
Let's consider we have a (simplified) model called post (of a blog) that would looks like this on the server-side:
<?php
namespace TYPO3\Blog\Domain\Model;
use Doctrine\ORM\Mapping as ORM;
use TYPO3\Flow\Annotations as Flow;
use MMitasch\Ember\Annotations as Ember;
/**
* A blog post
*
* @Flow\Entity
* @Ember\Resource
*/
class Post {
/**
* @var string
* @Flow\Validate(type="NotEmpty")
*/
protected $title;
/**
* @var string
* @Flow\Validate(type="NotEmpty")
*/
protected $content;
// getter and setter for each property omitted for simplification purposes
}
?>We will then generate the Ember Data model from the server-side semantics through our scaffolding mechanism. That would look like this:
App.Post = DS.Model.extend({
title: DS.attr('string'),
content: DS.attr('string')
});The Ember RESTAdapter assumes that the URLs and JSON associated with each model are conventional; this means that, if you follow the rules, you will not need to configure the adapter or write any code in order to get started.
We want to provide a REST JSON API that complies to the Ember RESTAdapter conventions.
The Ember RESTAdapter would expect the server-side API to look like this:
| Action | HTTP Verb | URL |
|---|---|---|
| Find | GET | /posts/123 |
| Find All | GET | /posts |
| Update | PUT | /posts/123 |
| Create | POST | /posts |
| Delete | DELETE | /posts/123 |
The payload for a GET request /posts/123 would look like this:
{
"post": {
"title": "Is a Automagical controller cool?",
"content": "Need to write some proper blog post content here!"
}
}There are two ways how we can define that we want to offer an endpoint for a certain model:
- Annotation in a Flow Domain Model
- Configuration in Ember.yaml
You might have noticed that in the comment before the php class definition, there was an Annotation added:
@Ember\ResourceIf a model has this added annotation, we will create an REST API for this model.
Additional to annotations we will provide a possibility to configure it inside a yaml-file. This is necessary as sometimes it might not be possible (eg. third party package) or wanted to add the annotation to the Flow domain model.
