FOSRestBundleを次のように構成しました。
#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
そして私はこれをコントローラーに持っています:
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);
}
}
しかし、次のURL app_dev.php/api/v1/reps
を試してみると、次のエラーが発生しました。
テンプレート ""が見つかりません。 500内部サーバーエラー-InvalidArgumentException3リンクされた例外:Twig_Error_Loader"InvalidArgumentException"InvalidArgumentException"
次の例のように、APIが整形式のJSONを返すことを期待しています。
{
"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"
}
FOSRestBundleはJSONを返すように構成されていませんか?なぜまだTwigテンプレートを要求するのですか?これを修正するにはどうすればよいですか?
最初のテスト:
@Jeetが私に示唆しているように、私はPostmanを使用してみました(彼が教えてくれた拡張子と同じです)。ヘッダーContent-Type
をapplication/json
に設定すると、エラーは次のようになります。
不正な形式のJSON
そのため、FOSRestBundleがヘッダーを適切に設定しておらず、コントローラーが有効なJSONを返していません。これらのヘッダーを修正するにはどうすればよいですか?
2番目のテスト:
@ Jeetが示唆するように、私はこのテストを実行します。
/**
* 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);
}
そして、それでも同じ問題:
テンプレート ""が見つかりません。 500内部サーバーエラー-InvalidArgumentException3リンクされた例外:Twig_Error_Loader"InvalidArgumentException"InvalidArgumentException"
ここで他に何が間違っている可能性がありますか?構成時に何かが足りませんでしたか?
最初にapp/config/routing.yml
とsrc/PDI/PDOneBundle/Resources/config/routing.yml
を追加するのを忘れたので、ここに進みます。おそらくこれはパズルの欠けている部分であり、問題がどこから来ているのかをよりよく理解できます。
#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: /
番目のテスト:
クライアント側からのリクエストに間違いなく問題があります。Postman
のようなツールを使用して適切なヘッダーを設定すると、必要に応じてエンティティを取得できます。下の図を参照してください。
問題がどこにあるのかわからないので、私はすでにアイデアがなくなっていたので、ここで誰かの助けがどうしても必要です
みんなが提案したように:Acceptヘッダーまたは拡張子だけがJSONを提供できます。 Acceptヘッダーでこれを並べ替えたようです。
拡張機能を使用するには、Symfonyでフォーマットをどのように設定するかを指示する必要があります。
このコードはあなたが望む出力を与えるはずです:
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:View
クラスを使用したくないが、純粋な配列を使用したい場合:SensioExtraBundleのビュー処理を禁止することを忘れないでください
sensio_framework_extra:
view: { annotations: false }
Edit2:HTML形式を使用せず、json出力のみが必要な場合は、次のような構成を使用できます。
fos_rest:
# ....
format_listener:
rules:
- { path: ^/, priorities: [ json ], fallback_format: json, prefer_extension: true }
# ....
「ビューが見つかりません」というエラーが表示される理由の説明:
TL; DR:ブラウザは、FOSRestBundleに「html」バリアントを出力するように指示するAcceptヘッダーを送信します。
背景:このバンドルは主にAcceptヘッダーで機能します。使用可能なすべての出力形式を用意することをお勧めします:html(REST APIを、指定したフォーム、オブジェクトのリスト、オブジェクトの詳細はこの方法で簡単に)、json、xml。デフォルトとしてimage/jpeg、image/png、バリアントとしてjson/xmlなどのイメージmimeタイプでさえある場合があります(base64イメージ表現を使用できます)。
説明:ブラウザの「ネットワーク」タブを開いて、送信されるヘッダーを確認すると、次のようになります。text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
これは「そのような順序で使用する」ことを意味します:
これに近づけると、構成に応じてtext/htmlが構成のバリアントの1つ( 'html')であり、 */*は別のもの( 'json')ですが、text/htmlの優先度は1ですが、*/*の優先度は0.8なので、text/htmlが一致し、FOSRestBundleはHTML表現を見つけようとして失敗します。
PS:質問を複数回投稿する場合は、すべてのスレッドですべての回答に注意してください。
あなたは2つの方法で応答を与えることができます
return View::create($entities, Codes::HTTP_OK);
または
$view = $this->view($entities, Codes::HTTP_OK);
return $this->handleView($view)
簡単に使用できます
$view = new View($form);
$view->setFormat('json');
return $this->handleView($view);
FosRestBundleはAcceptヘッダーを利用します。これは、要求した内容に基づいて応答を返すことを意味します。ルート「app_dev.php/api/v1/reps」にアクセスすることにより、暗黙的にhtml形式を要求しているため、テンプレートを提供しようとします。
App_dev.php/api/v1/reps.jsonは必要なものを返しますか?
また、app_dev.php/api/v1/reps.xmlをテストし、xml出力を期待する必要があります