2015-05-08 7 views
9

I FOSRestBundle wie folgt konfiguriert haben:FOSRestBundle Setup für JSON Rückkehr aber immer noch fragen für Twig Vorlage

#FOSRestBundle 
fos_rest: 
    param_fetcher_listener: true 
    body_listener: true 
    format_listener: 
     rules: 
      - { path: ^/, priorities: [ json, html ], fallback_format: ~, prefer_extension: true } 
     media_type: 
      version_regex: '/(v|version)=(?P<version>[0-9\.]+)/' 

    body_converter: 
     enabled: true 
     validate: true 

    view: 
     mime_types: 
      json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1'] 
     view_response_listener: 'force' 
     formats: 
      xml: false 
      json: true 
     templating_formats: 
      html: true 

    exception: 
     codes: 
      'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404 
      'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT 
     messages: 
      'Symfony\Component\Routing\Exception\ResourceNotFoundException': true 
    allowed_methods_listener: true 
    access_denied_listener: 
     json: true 

Und ich habe dies an Controller:

namespace PDI\PDOneBundle\Controller\Rest; 

use FOS\RestBundle\Controller\FOSRestController; 
use Nelmio\ApiDocBundle\Annotation\ApiDoc; 
use FOS\RestBundle\Controller\Annotations\QueryParam; 
use FOS\RestBundle\Controller\Annotations\Get; 

class RepresentativeRestController extends FOSRestController 
{ 
    /** 
    * Get all representatives. 
    * 
    * @return array 
    * 
    * @ApiDoc(
    * resource = true, 
    *  https = true, 
    * description = "Get all representatives.", 
    * statusCodes = { 
    *  200 = "Returned when successful", 
    *  400 = "Returned when errors" 
    * } 
    *) 
    * @Get("/api/v1/reps") 
    */ 
    public function getRepsAction() 
    { 
     $em = $this->getDoctrine()->getManager(); 
     $entities = $em->getRepository('PDOneBundle:Representative')->findAll(); 

     if(!$entities) 
     { 
      return $this->view(null, 400); 
     } 

     return $this->view($entities, 200); 
    } 
} 

Aber wenn ich die folgende URL versuchen app_dev.php/api/v1/reps Ich habe diesen Fehler:

Unable to find template "". 500 Internal Server Error - InvalidArgumentException 3 linked Exceptions: Twig_Error_Loader » InvalidArgumentException » InvalidArgumentException »

Ich erwarte, dass API eine gut geformte JSON ein s das folgende Beispiel:

{ 
    "id":"30000001", 
    "veeva_rep_id":"0055648764067SwzAAE", 
    "display_name":"John Know", 
    "avatar_url":"http://freelanceme.net/Images/default%20profile%20picture.png", 
    "rep_type":"VEEVA", 
    "username":"[email protected]", 
    "first":"John", 
    "last":"Know", 
    "title":"Sales Representative", 
    "phone":"800-555-1212", 
    "email":"[email protected]", 
    "territory_id":"200454001", 
    "inactive":"no", 
    "total_contacts":"6", 
    "total_shares":"0", 
    "totalViews":"0", 
    "lastLoginAt":"2015-05-05 15:45:57", 
    "lastVeevaSyncAt":"2015-05-05 15:45:57", 
    "createdAt":"2015-05-05 15:45:57", 
    "updatedAt":"2015-05-05 15:45:57" 
} 

Ist FOSRestBundle nicht für die Rückgabe von JSON konfiguriert? Warum fragst du noch nach Twig-Vorlage? Wie kann ich das beheben?

Erster Test:

Als @Jeet mich schlage ich habe mit Postman versucht (die gleiche wie die Erweiterung ist er mir gesagt) und nach dem Header Content-Type zu application/json der Fehler verwandelt sich in diesem

gesetzt

Malformed JSON

Also, die FOSRestBundle ist nicht einrichten Header wie sollte sein und Controller gibt keine gültige JSON, wie repariere ich diese?

Zweiter Test:

Wie @Jeet vorgeschlagen Ich betreibe diesen Test:

/** 
* Get all representatives. 
* 
* @return array 
* 
* @ApiDoc(
* resource = true, 
*  https = true, 
* description = "Get all representatives.", 
* statusCodes = { 
*  200 = "Returned when successful", 
*  400 = "Returned when errors" 
* } 
*) 
* @Get("/api/v1/reps") 
* @View() 
*/ 
public function getRepsAction() 
{ 
    $em = $this->getDoctrine()->getManager(); 
    $entities = $em->getRepository('PDOneBundle:Representative')->findAll(); 

    $temp = array("1", "2", "3"); 

    $view = $this->view($temp, Codes::HTTP_OK); 
    return $this->handleView($view); 
} 

Und noch das gleiche Problem:

Unable to find template "". 500 Internal Server Error - InvalidArgumentException 3 linked Exceptions: Twig_Error_Loader » InvalidArgumentException » InvalidArgumentException »

Was sonst kann falsch sein Hier? Hab ich bei der Konfiguration etwas übersehen?

Ich vergaß app/config/routing.yml und src/PDI/PDOneBundle/Resources/config/routing.yml zunächst hinzuzufügen, so hier sie geht, vielleicht ist dies das fehlende Stück auf dem Puzzle ist und gibt Ihnen eine bessere Vorstellung davon, wo das Problem kommt von:

#app/config/routing.yml 
#PDOne 
pdone: 
    resource: "@PDOneBundle/Resources/config/routing.yml" 

template: 
    resource: "@TemplateBundle/Resources/config/routing.yml" 

#FOSUserBundle 
fos_user: 
    resource: "@FOSUserBundle/Resources/config/routing/all.xml" 
    prefix:/

#NelmioApiDocBundle: 
NelmioApiDocBundle: 
    resource: "@NelmioApiDocBundle/Resources/config/routing.yml" 
    prefix: /api/doc 

#SonataAdmin 
admin: 
    resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml' 
    prefix: /admin 

_sonata_admin: 
    resource: . 
    type: sonata_admin 
    prefix: /admin 

#src/PDI/PDOneBundle/Resources/config/routing.yml 
pdone: 
    resource: "@PDOneBundle/Controller/" 
    type:  annotation 
    prefix: /

Dritten Test : wenn ich ein Tool wie Postman und stellen Sie die richtigen Header verwende ich die Entitäten bekam, wie ich will,

Definitiv ist etwas, mit Anforderung von Client-Seite falsch, siehe Bild unten:

enter image description here

ich nicht finden können, wo das Problem was ich brauche so dringend jemand hier helfen, weil ich schon die Ideen

+0

Haben Sie "Content-Type" als "application/json" konfiguriert? – Jeet

+0

@Jeet wo soll ich das machen? Ist die Konfiguration von FOSRes nicht so, wie Sie auf dem OP sehen können? – ReynierPM

+0

Probieren Sie app_dev.php/api/v1/reps in der Advanced Rest Client-Anwendung von Google Chrome aus (App-Erweiterung), dort haben Sie eine Option. – Jeet

Antwort

21

Wie Jungs vorgeschlagen: nur Accept Header oder Erweiterung könnte Ihnen ein JSON geben. Scheint, als ob du das mit Accept-Header sortiert hast.

Um die Erweiterung zu verwenden, müssen Sie sagen, wie Sie in Symfony formatieren möchten.

Sie Dieser Code sollten Sie eine Ausgabe geben möchten:

namespace RestTestBundle\Controller; 

use FOS\RestBundle\Controller\Annotations\View; 

use FOS\RestBundle\Controller\Annotations\Get; 

class YourController 
{ 
    /** 
    * @Get("/api/v1/reps.{_format}", defaults={"_format"="json"}) 
    * @View() 
    */ 
    public function indexAction() 
    { 
     return array(
      'status' => 'ok', 
      'companies' => array(
       array('id' => 5), 
       array('id' => 7), 
      ), 
     ); 
    } 
} 

Edit1: Wenn Sie eine View Klasse nicht verwenden wollen, sondern reine Arrays: vergessen Sie nicht anzeigen Umgang mit SensioExtraBundle

zu verbieten
sensio_framework_extra: 
    view: { annotations: false } 

Edit2: Wenn Sie keine HTML-Format verwenden und wollen nur eine json Ausgang haben, können Sie solche fonfiguration verwenden:

fos_rest: 
    # .... 
    format_listener: 
     rules: 
      - { path: ^/, priorities: [ json ], fallback_format: json, prefer_extension: true } 
    # .... 

Erklärung, warum Sie einen Fehler „-Ansicht nicht gefunden“ sehen:

TL; DR: Browser-Header ein Akzeptieren senden, die FOSRestBundle zur Ausgabe einer ‚html‘ Variante erzählt.

Hintergrund: Dieses Bundle funktioniert hauptsächlich mit Accept-Headern. Es ist eine gute Praxis, alle möglichen Ausgabeformate zur Verfügung zu haben: html (Sie können Ihre REST-API mit von Ihnen bereitgestellten Formularen, Listen von Objekten, Details von Objekten leicht testen Weg), json, xml. Manchmal sogar Image-Mime-Typen wie image/jpeg, image/png als Standard oder json/xml als Variante (Sie können die base64-Bilddarstellung verwenden).

Erklärung: Wenn Sie ein „Netzwerk“ Tab des Browsers öffnen und Header überprüfen sendet es Ihnen so etwas wie bemerken: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 die „Verwendung in einer solchen Ordnung“ bedeutet:

  1. text/html
  2. application/xhtml + xml
  3. application/xml mit Priorität 0,9 die verboten nach Ihrem c ONFIGURATION
  4. */* mit Priorität 0,8 dem meand jedes Format

Wenn Sie diese Nähe suchen ist, dass nach Ihrer Konfiguration Text sehen/html ist eine der Varianten, die Ihre Konfiguration hat ('html') und */* ist ein anderer ('json'), aber text/html hat eine Priorität von 1, während */* hat eine Priorität von 0.8, so Text/html Übereinstimmungen und FOSRestBundle versucht, eine HTML-Darstellung zu finden und schlägt fehl.

PS: Wenn Sie mehrere Fragen stellen, achten Sie bitte auf alle Antworten in jedem Thread.

+0

Große Antwort Artem L !! Es hat mir sehr geholfen ... Vielen Dank. –

1

FosRestBundle nutzt die Accept-Header war. Dies bedeutet, dass eine Antwort basierend auf Ihren Anforderungen zurückgegeben wird. Wenn Sie auf die Route "app_dev.php/api/v1/reps" zugreifen, fordern Sie implizit ein HTML-Format an und versuchen daher, eine Vorlage bereitzustellen.

Tut app_dev.php/api/v1/reps.Json zurück, was Sie brauchen?

Sie sollten auch testen app_dev.php/api/v1/reps.xml und erwarten, dass eine XML-Ausgabe

+1

Keiner dieser drei funktioniert für mich, wenn ich '.html' oder' .json' oder '.xml' setze, habe ich 404 route error, ich kann nicht finden, was ich in meiner Konfiguration oder auf der Controllerseite – ReynierPM

+0

vermisse Ihre Antwort hat die Lösung, aber sie ist implizit im Inhalt enthalten. Du solltest das speziell zum Testen mit einigen Clients wie Chrome/Firefox RestClient Extension beschreiben. MÜSSTE den richtigen Header setzen: Akzeptieren: application/json – le0diaz

2

Sie können Antwort auf zwei Arten geben

return View::create($entities, Codes::HTTP_OK); 

oder

$view = $this->view($entities, Codes::HTTP_OK);  
return $this->handleView($view) 
+0

Das funktioniert aber nur von der Postman Chrome Erweiterung, indem man die richtigen Header für 'Content-Type 'setzt 'Wenn ich vom Browser aus versuche, habe ich das gleiche Problem mit dem Templating, was mich fragen lässt: Warum? Wo ist das Problem bei der Konfiguration und warum ist die Header-Einstellung nicht richtig? Ich gebe auch gerne eine Art 'NotFoundException' zurück, wenn es nicht '$ entities' gibt, kannst du mir zeigen, wie das auf deinem Code zu erreichen ist? – ReynierPM