Skip to content

Commit

Permalink
Update doc
Browse files Browse the repository at this point in the history
  • Loading branch information
bakura10 committed Feb 17, 2014
1 parent ca13fa9 commit 2368b97
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 24 deletions.
47 changes: 26 additions & 21 deletions docs/02. Quick Start.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,23 +212,23 @@ class UserController extends AbstractRestfulController
*/
protected $userService;

public function delete(User $user, ResourceMetadataInterface $metadata)
public function delete(User $user)
{
$this->userService->delete($user);
}

public function put(User $user, ResourceMetadataInterface $metadata)
public function put(User $user)
{
$this->userService->update($user);

return $user;
return $this->resourceModel($user);
}

public function get(User $user, ResourceMetadataInterface $metadata)
public function get(User $user)
{
// Do things if you want

return $user;
return $this->resourceModel($user);
}
}
```
Expand All @@ -239,16 +239,17 @@ you from using a normal ZF2 controller for some actions).
As you can guess, each "action" is named after the corresponding HTTP method. ZfrRest is flexible enough that you can
add custom HTTP verbs by adding specific method handlers and more public methods in your controller.

The interesting thing is that, contrary to traditional ZF2 controllers, you receive parameters in each method: the
actual resource (in this case, a User) as well as the resource metadata for the resource that has been matched by
the router. You have nothing to do, this is done automatically by ZfrRest, so that your controller stays really clean.
The only thing you need to do is **passing the resource to the service for your business logic**.
The interesting thing is that, contrary to traditional ZF2 controllers, you receive parameter in each method: the
actual resource data (in this case, a User) for the resource that have been matched by the router. You have nothing
to do, this is done automatically by ZfrRest, so that your controller stays really clean. The only thing you need
to do is **passing the resource to the service for your business logic**.

For the `put` method, you don't even need to manually validate the user data, because it has already been validated
using the input filter you specified in the mapping. If data would have been invalid, it would have returned a
400 Bad Request error, with the various error messages under the `errors` key.

If you want automatic serialization of the resource, you must return a ResourceModel (it needs a resource).
If you want automatic serialization of the resource, you must return a ResourceModel (it needs a resource). ZfrRest
provides you a utility controller plugin called `resourceModel` that you can use to create one.

Now, let's see the `Application\Controller\UsersController` controller:

Expand All @@ -258,7 +259,7 @@ Now, let's see the `Application\Controller\UsersController` controller:
namespace Application\Controller;

use Application\Entity\User;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Selectable;
use DoctrineModule\Paginator\Adapter\Collection as CollectionAdapter;
use Zend\Paginator\Paginator;
use ZfrRest\Mvc\Controller\AbstractRestfulController;
Expand All @@ -270,35 +271,39 @@ class UsersController extends AbstractRestfulController
*/
protected $userService;

public function post(User $user, ResourceMetadataInterface $metadata)
public function post(User $user)
{
$this->userService->create($user);

return new ResourceModel(new Resource($user, $metadata));
return $this->resourceModel($user);
}

public function get(Collection $users, ResourceMetadataInterface $metadata)
public function get(Selectable $users)
{
// We can do filtering here on the collection, for example using the Doctrine API criteria

// We could also wrap the collection around a paginator
$paginator = $this->paginatorWrapper($users);
$paginator->setCurrentPageNumber($this->params()->fromQuery('page', 1));

return new ResourceModel(new Resource($user, $metadata));
return $this->resourceModel($paginator);
}
}
```

For the `post` method, it is exactly the same as the `put` method: you don't need to validate anything, because
it has already been done for you. Just pass the entity to your service and you're done!

For the `get` method, we receive a Collection. Actually, if you are using Doctrine ORM, you can typehint to
For the `get` method, we receive a Selectable. Actually, if you are using Doctrine ORM, you can typehint to
`Doctrine\Common\Collections\Selectable`, which is a much more useful interface because it allows to do efficient
filtering.

As you can see from the example, we can also wrap the data around a Zend paginator, and directly return the
paginator. The `paginatorWrapper` is a simple controller plugin that encapsulate the logic of paginator creation.
> Most of the time, an object that implements the `Selectable` interface also implement `Collection` interface. However,
the `Selectable` interface is much more flexible as it has powerful filtering capabilities. That's why you should
always typehint to `Selectable` if you are using Doctrine ORM or Doctrine ODM.

This comment has been minimized.

Copy link
@danizord

danizord Feb 17, 2014

Contributor

IIRC ODM DocumentManager does not implement Selectable.

This comment has been minimized.

Copy link
@bakura10

bakura10 Feb 17, 2014

Author Member

It does now :). I've broguht support for it. ODM only lack support of Selectable for PersistentCollection iirc


As you can see from the example, we can also wrap the data around a Zend paginator, and then wrap it around
a `ResourceModel`. The `paginatorWrapper` is a simple controller plugin that encapsulate the logic of paginator creation.
You can also optionally pass it a criteria to filter the collection (see the cookbook).

When you return a Paginator, ZfrRest will intelligently serialize the output. For instance, here is an example
Expand Down Expand Up @@ -468,14 +473,14 @@ defined a controller `Application\Controller\TweetsController`. We therefore nee

namespace Application\Controller;

use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Selectable;
use ZfrRest\Mvc\Controller\AbstractRestfulController;

class TweetsController extends AbstractRestfulController
{
public function get(Collection $tweets)
public function get(Selectable $tweets)
{
return $tweets;
return $this->resourceModel($tweets);
}
}
```
Expand Down
6 changes: 3 additions & 3 deletions docs/07. Cookbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function get(Selectable $users)
$paginator = $this->paginatorWrapper($users);
$paginator->setCurrentPageNumber($this->params()->fromQuery('page', 1));

return $paginator;
return $this->resourceModel($users);

This comment has been minimized.

Copy link
@Orkin

Orkin Feb 17, 2014

Member

$paginator not $users ?

This comment has been minimized.

Copy link
@bakura10

bakura10 Feb 17, 2014

Author Member

Yes you're right, I'll change that.

}
```

Expand All @@ -101,7 +101,7 @@ public function get(Selectable $users)
$paginator = $this->paginatorWrapper($users, $criteria);
$paginator->setCurrentPageNumber($this->params()->fromQuery('page', 1));

return $paginator;
return $this->resourceModel($users);

This comment has been minimized.

Copy link
@Orkin

Orkin Feb 17, 2014

Member

Idem

}
```

Expand All @@ -123,7 +123,7 @@ public function get(Selectable $users)
$paginator = $this->paginatorWrapper($users, $criteria);
$paginator->setCurrentPageNumber($this->params()->fromQuery('page', 1));

return $paginator;
return $this->resourceModel($users);

This comment has been minimized.

Copy link
@Orkin

Orkin Feb 17, 2014

Member

Idem

}
```

Expand Down

0 comments on commit 2368b97

Please sign in to comment.