Symfony2 FOSRestBundle overrides default application - symfony

I'm using FOSRestBundle to manage my api. I already have a running sf2 application, and i want to allow third person to access some of my application features. I configured my api, and it works as expected, i can consume my api route with success
for example :
GET http://my.domain.ldt/api/v1/users
My Api only handle json format, here is my fos_rest configuration :
fos_rest:
param_fetcher_listener: true
body_listener: true
format_listener: true
view:
view_response_listener: 'force'
exception_wrapper_handler: My\ApiBundle\Handlers\ApiExceptionWrapperHandler
formats:
json : true
failed_validation: HTTP_BAD_REQUEST
templating_formats:
html: false
xml: false
routing_loader:
default_format: json
include_format: false
exception:
enabled: true
service:
view_handler: my.view_handler
services:
my.json_handler:
class: My\ApiBundle\Handlers\JsonHandler
my.view_handler:
parent: fos_rest.view_handler.default
calls:
- ['registerHandler', [ 'json', ["#my.json_handler", 'createResponse'] ] ]
As i said, my Api works well, but i face a major problem : When i try to access to the main application from my web browser, ( http://my.domain.ldt/, or http://my.domain.ldt/login), i get the following response instead of my classic web page :
An Exception was thrown while handling: No matching accepted Response format could be determined
Why my fos_rest conf applies on my main website ? Is it possible to only set the api conf for the api routes ? Did i miss something ?

The problem is that you forgot to define rules for FOSRestBundle's format listener.
In fact I'm not sure you need this listener as it seems you use json as the default format. The format listener will try to match the Accept header and extract the current request format based on it. So except if you want to support other formats than json for your api, you can just not use it.
In case you want to fix it instead of removing it, you have to update your config with something like:
fos_rest:
format_listener:
enabled: true
rules:
- { path: '^/', priorities: ['json', 'xml', 'html], fallback_format: 'json' }
Of course you can change this rule to have a different rule for your api:
fos_rest:
format_listener:
enabled: true
rules:
- { path: '^/api', fallback_format: 'json' }
- { path: '^/', fallback_format: 'html' }

Related

Unable change Swagger UI location path

I made an api with api-platform.
I tried to edit the swagger_ui path '/' to '/docs' according to api-platform documentation and allow '/' redirect to custom twig i made.
The swagger_ui documentation is available in /docs path but also still available in '/' path instead of my custom twig file.
Here is my config :
app/config/packages/api_platform.yaml
api_platform:
mapping:
paths: ['%kernel.project_dir%/src/Entity']
enable_swagger_ui: true
enable_re_doc: true
enable_docs: true
app/config/routes/api_platform.yaml
api_platform:
resource: .
type: api_platform
prefix: /
app/config/route.yaml
swagger_ui:
path: /docs
controller: api_platform.swagger.action.ui
hello-world:
path: /
controller: App\Controller\HelloController::index
Thanks by advance for your answer, if i haven't be clear, just le me know :)
Try changing
api_platform:
mapping:
paths: ['%kernel.project_dir%/src/Entity']
enable_swagger_ui: true
enable_re_doc: true
enable_docs: true
with
api_platform:
mapping:
paths: ['%kernel.project_dir%/src/Entity']
enable_swagger_ui: true
enable_re_doc: true
enable_docs: true
and pay attention to indentation in other files ...
This seems to be broken for now. There's a PR to fix the issue inside Api Platform but it hasn't been merged yet: https://github.com/api-platform/core/pull/2749

Silverstripe Restfulapi configuration

I try the Restfulapi addon for silverstripe 4 and my configuration is:
integre\About:
api_access: true
integre\Home:
api_access: true
Image:
api_access: true
File:
api_access: true
integre\Theatre:
api_access: true
# RestfulAPI config
Colymba\RESTfulAPI\RESTfulAPI:
authentication_policy: false
access_control_policy: 'ACL_CHECK_CONFIG_AND_MODEL'
cors:
Enabled: true
Allow-Origin: '*'
Allow-Headers: '*'
Allow-Methods: 'OPTIONS, POST, GET, PUT, DELETE'
Max-Age: 86400
but when i try http://localhost/integre/api/Theatre/1 i receive
{
"code": 400,
"message": "Model does not exist. Received 'Theatre'."
}
how to fix this?
Your problem is that you're using a namespaced class and not correctly configuring it to be used in the API, so it's not resolving correctly. Looking at DefaultQueryHandler, you need to define a class name map for this:
Colymba\RESTfulAPI\QueryHandlers\DefaultQueryHandler:
models:
Theatre: integre\Theatre
This tells the query handler to load integre\Theatre when it is asked for a Theatre model. Note that your Image and File references in your configuration are also missing their namespaces.

CORS errors with Symfony 4 & Nelmio CORS Bundle

I've been trying to figure out why I'm getting CORS issues with my Symfony 4 API application I've just deployed to my Apache server and can't make any sense of the issue.
config/packages/nelmio_cors.yaml
nelmio_cors:
defaults:
origin_regex: true
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
max_age: 3600
paths:
'^/': ~
.env
...
CORS_ALLOW_ORIGIN=/*/
...
All responses from requests I make from my localhost front-end application to that API contain no Access-Control-Allow-Origin header, and I get the standard error;
Access to XMLHttpRequest at 'http://my-api.com/foo' from origin
'http://localhost:4200' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
No special headers are being sent and for now I've set the allowed origin regex to "all" so I can't work out what is causing issue here. I've even checked within the cache to ensure the origin is being correctly pulled from the env variables, which it is. If other context/file content is required to assist please let me know!
I always try to be a bit more specific for allowing CORS like:
CORS_ALLOW_ORIGIN=^http://(.*:8080|localhost:4200)$
what you could try if you really want to enable all origins would be something like:
CORS_ALLOW_ORIGIN=^.*$
Your problem is that you've opted to use a regular expression (origin_regex: true) but not provided valid pattern.
If you want to use origin_regex: true then you should specify a valid pattern such as .* or ^.*$.
If you don't want to use a regular expression then omit the origin_regex setting (or set it to false) and just use * as your CORS_ALLOW_ORIGIN value.
I've resolved the issue, and although on the surface it appeared to be related to the CORS configuration, it was actually misconfiguration of the project on the server.
TL;DR is that the project was missing a .htaccess file which I didn't require in development due to using Valet - following the instructions here resolved the issue.
Why do you need nelmio?
You can have simple event listener(on kernel.event_subscriber) adding these headers.
namespace App\EventListener\HttpKernel;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
class CorsSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
KernelEvents::RESPONSE => 'onResponse'
];
}
public function onResponse(FilterResponseEvent $filterResponseEvent)
{
$response = $filterResponseEvent->getResponse();
$response->headers->set('Access-Control-Allow-Origin', '*');
}
}
Register it as kernel.event_subscriber
app.http_kernel.cors_subscriber:
class: App\EventListener\HttpKernel\CorsSubscriber
tags:
- { name: kernel.event_subscriber }

Symfony with combination of Basic Routing and REST

My existing application requires additional RESTful endpoints.
I've added FOSRestBundle with the following configuration.
fos_rest:
param_fetcher_listener: true
view:
mime_types:
json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1', 'application/json;version=1.2']
view_response_listener: 'force'
formats:
xml: false
json: true
templating_formats:
html: false
format_listener:
rules:
- priorities: [json, xml]
- fallback_format: json
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
body_listener: true
routing_loader:
default_format: json
include_format: false
The REST requests are fine but the basic routing now doesn't work
With the following error
This page contains the following errors:
error on line 11 at column 92: EntityRef: expecting ';'
Below is a rendering of the page up to the first error.
Basically I just want to combine the basic routing with rest
You can solve this by disabling the format listener for your specific html routes (see http://symfony.com/doc/current/bundles/FOSRestBundle/format_listener.html#disabling-the-format-listener-via-rules)
So, add a rule for the format listener in your config.yml like this:
format_listener:
rules:
- { path: '^/my-html-routes', stop: true }
- { path: '^/api', priorities: ['json', 'xml'], fallback_format: json }

415 Unsupported Media Type

I followed this link
when I run this command to see if the Get method works very well I have this error displayed in my terminal ERROR 415: Unsupported Media Type.
I'm going to see my source code :
1- First I set my config file :
#app/config/config.yml
sensio_framework_extra:
view:
annotations: false
fos_rest:
param_fetcher_listener: true
body_listener: true
format_listener: true
view:
view_response_listener: 'force'
2- After i just fix my routing file :
#app/config/routing.yml
minn_ads_api:
resource: "#MinnAdsAPIBundle/Resources/config/routing.yml"
type: rest
3- I have also set the routing file in my *AdsAPIBundle :*
#AdsAPIBundle/Resources/config/routing.yml
brend:
type: rest
resource: Minn\AdsAPIBundle\Controller\BrendController
4- Under my AdsAPIBundle I just insert the function :
#src/BundleApi/Controller/BrendController.php
/**
* #Rest\View
* #Rest\Get("/api/brend/{id}", requirements={"id" = "\d+"}, defaults={"id" = 1})
*/
public function getAction($id) {
$repo = $this->getDoctrine()->
getManager()->
getRepository("MinnAdsBundle:Brend");
$brend = $repo->find($id);
return array('brend' => $brend);
}
Maybe you need to add a default format:
# app/config/config.yml
fos_rest:
routing_loader:
default_format: json

Resources