Symfony 2: Fos RestBundle vraag
Ik ben bezig met rest services opzetten binnen symfony 2. Ik ben begonnen met eerst volledig handmatig die services opzetten en dat gaat ok. Ben nu op het punt dat ik er toch iets verder mee wil en ben op de FOS restbundle uitgekomen. Nu ben ik een tutorial aan het volgen en het gaat overal goed m.u.v. het laatste gedeelte. Als ik de service aanroep krijg ik de volgende foutmelding:
The controller must return a response (Array(users => Array(0 => Object(Screenfony\DemoBundle\Entity\User), 1 => Object(Screenfony\DemoBundle\Entity\User))) given)
De tutorial die ik volg is: http://www.screenfony.com/lessons/symfony-rest-api-1/ (is een beginners filmpje voor de bundle).
Ik heb alles exact 1 op 1 gevolgd (heb alleen pas 1 service i.p.v. 2) alleen bij het aanroepen gaat het niet goed.
userscontroller
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace Screenfony\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use FOS\RestBundle\Controller\Annotations\View;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
class UsersController extends Controller{
//put your code here
/*
* @return array
* @View()
*/
public function getUsersAction()
{
$users= $this->getDoctrine()->getRepository('ScreenfonyDemoBundle:User')->findAll();
return (array('users' => $users));
}
}
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use FOS\RestBundle\Controller\Annotations\View;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
class UsersController extends Controller{
//put your code here
/*
* @return array
* @View()
*/
public function getUsersAction()
{
$users= $this->getDoctrine()->getRepository('ScreenfonyDemoBundle:User')->findAll();
return (array('users' => $users));
}
}
Stukje uit config.yml
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
sensio_framework_extra:
view: { annotations:false}
router: { annotations:true}
fos_rest:
format_listener:
rules:
- prefer_extension: false
view:
view_response_listener: true
view: { annotations:false}
router: { annotations:true}
fos_rest:
format_listener:
rules:
- prefer_extension: false
view:
view_response_listener: true
Als ik mijn users dump na het ophalen met exit(\Doctrine\Common\Util\Debug::dump($users)); zie ik wel dat mijn gebruikers correct worden opgehaald.
Als ik dus alles zie wordt de service goed aangeroepen de gebruikers worden goed opgehaald alleen de response gaat niet goed. Heb met curl verschillende headers meegegeven maar geen resultaat.
Heb dus al een tijdje dingen zitten uitproberen maar loop nu toch echt vast met dit. Heeft iemand enige ideeen waar het aan kan liggen?
De foutmelding is eigenlijk best wel duidelijk. Je roept een Action aan vanuit de browser. Dan moet er ook een antwoord verstuurd worden vanaf de server. In Symfony gebruik je hiervoor ALTIJD een Response object. voor iedere Action is dus een Response object vereist.
Jij retourneert vanuit getUsersAction() een array en geen Response object. Wat voor een beginner lastig te doorgronden is dat je een Response object kunt retourneren met statische content maar je kunt ook een Twig template gebruiken om je content op te bouwen. Het resultaat van deze template wordt echter gewoon weer aan het response object meegegeven. Daarnaast kun je de Controller::render functie laten weten welke template ze moet gebruiken aan de hand van een parameter of middels annotations. Deze render() functie geeft een compleet Response object terug.
Retourneer een response object zonder template:
Code (php)
Retourneer een response object middels een template en zonder gebruik te maken van annotations:
Code (php)
Retourneer een response object middels een template met gebruik van annotations:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class UsersController extends Controller
{
/**
* Lists all Users.
*
* @Route("/", name="app_users")
* @Method("GET")
* @Template("AppBundle:Default:index.html.twig")
*/
public function getUsersAction()
{
return array('users' => $users);
}
}
?>
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class UsersController extends Controller
{
/**
* Lists all Users.
*
* @Route("/", name="app_users")
* @Method("GET")
* @Template("AppBundle:Default:index.html.twig")
*/
public function getUsersAction()
{
return array('users' => $users);
}
}
?>
Zie voor uitgebreide info: http://symfony.com/doc/current/book/controller.html
Gewijzigd op 30/07/2015 17:46:42 door Frank Nietbelangrijk
In dit geval zal de ViewResonseListener van FOSRestBundle de array moeten serializen (als het een XML/JSON request betreft) of de template renderen. Dit omdat deze action is getagged met de @FOS\RestBundle\Annotations\View() annotation.
Ik heb geen idee waarom dit hier niet werkt, al geprobeerd de cache te verschonen?
Als ik app/console route:debug doe zie ik dat de route wel correct wordt gevonden, alleen het response object retourneren niet.
Ik ga vanmiddag even kijken of ik het voor mekaar kan krijgen om het zonder de annotations te doen (dus de view in de functie aanmaken). Misschien dat om de 1 of andere reden de annotations niet goed gaan.
Toevoeging op 31/07/2015 13:39:34:
Heb inmiddels getest zonder de annotations en dan gaat het goed. Dus ga hier voorlopig even mee verder.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
public function getTestAction()
{
$data = new TestClass();
$data->setTestVar("dit is een testvar");
$data2 = new TestClass();
$data2->setTestVar("dit is data 2");
$returnArray = array($data, $data2);
$view = View::create()->setData(array('gegevens' => $returnArray));
return $this->getViewHandler()->handle($view);
}
{
$data = new TestClass();
$data->setTestVar("dit is een testvar");
$data2 = new TestClass();
$data2->setTestVar("dit is data 2");
$returnArray = array($data, $data2);
$view = View::create()->setData(array('gegevens' => $returnArray));
return $this->getViewHandler()->handle($view);
}
Heel raar zoek later wel uit waaorm het met annotations niet goed gaat. Loop nu weer tegen het probleem op dat hij nu bij 'elke' route die ik heb er een REST service van maakt (wat niet de bedoeling is aangezien sommige routes gewoon een webpagina moeten tonen).
Gewijzigd op 31/07/2015 13:40:49 door ama saril