我想使用symfony php框架创建自己的Restful API。 当然,我用 - FOSRestBundle - FOSUserBundle - LexikJWTAuthenticationBundle - JMSSerializerBundle
配置完所有捆绑包后,我的API返回空对象。
[{}{}{}{}{}{}{}]
在我的控制器中我写
class ChantController extends Controller
{
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$chants = $em->getRepository(Chant::class)->findAll();
return new JsonResponse($chants);
}
}
由LexikJWTAuthenticationBundle创建的登录api可以正常工作,但是我自己的路由不起作用。 这是我的配置文件
app / config / config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
- { resource: "@ChantBundle/Resources/config/services.yml" }
- { resource: "@UserBundle/Resources/config/services.yml" }
- { resource: "@AdminBundle/Resources/config/services.yml" }
- { resource: "@JsonApiBundle/Resources/config/services.yml" }
- { resource: "@AjaxApiBundle/Resources/config/services.yml" }
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: fr
jms_serializer.camel_case_naming_strategy.class: JMS\Serializer\Naming\IdenticalPropertyNamingStrategy
framework:
#esi: ~
translator: { fallbacks: ['%locale%'] }
secret: '%secret%'
router:
resource: '%kernel.project_dir%/app/config/routing.yml'
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
default_locale: '%locale%'
trusted_hosts: ~
session:
# https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
handler_id: session.handler.native_file
save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
fragments: ~
http_method_override: true
assets: ~
php_errors:
log: true
templating:
engines: ['twig']
serializer:
enabled: false
# Twig Configuration
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
# Doctrine Configuration
doctrine:
dbal:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
# Swiftmailer Configuration
swiftmailer:
transport: '%mailer_transport%'
host: '%mailer_host%'
username: '%mailer_user%'
password: '%mailer_password%'
spool: { type: memory }
# FOSUserbundle Configuration
fos_user:
db_driver: orm # Le type de BDD à utiliser, nous utilisons l'ORM Doctrine depuis le début
firewall_name: main # Le nom du firewall derrière lequel on utilisera ces utilisateurs
user_class: Root\ModelsBundle\Entity\User\User # La classe de l'entité User que nous utilisons
# group:
# group_class: Root\ModelsBundle\Entity\User\Group
# form:
# type: Root\UserBundle\Form\Type\GroupType
# registration:
# confirmation:
# enabled: true
# template: UserBundle:Registration:email.html.twig
# form:
# type: Root\UserBundle\Form\RegistrationType
# validation_groups: [public_registration, Registration]
# profile:
# form:
# type: Root\UserBundle\Form\Type\ProfileFormType
# validation_groups: [public_edit, Default]
# resetting:
# email:
# template: UserBundle:Resetting:email.html.twig
from_email:
address: "%mailer_user%"
sender_name: CHORISTER_USER
# service:
# mailer: fos_user.mailer.twig_swift
nelmio_api_doc: ~
# JMS Serializer
jms_serializer:
metadata:
auto_detection: true
handlers:
datetime:
default_format: "Y-m-d\\TH:i:sP"
default_timezone: "UTC"
fos_rest:
body_converter:
enabled: true
format_listener:
rules:
- { path: '^/api', priorities: ['json'], fallback_format: json, prefer_extension: false }
- { path: '^/', priorities: ['html'], fallback_format: html, prefer_extension: false }
view:
view_response_listener: force
formats:
json: true
xml: false
routing_loader:
default_format: json
serializer:
serialize_null: true
param_fetcher_listener: true
body_listener: true
access_denied_listener:
json: true
# Lexik JWT Auth
lexik_jwt_authentication:
private_key_path: '%jwt_private_key_path%'
public_key_path: '%jwt_public_key_path%'
pass_phrase: '%jwt_key_pass_phrase%'
token_ttl: '%jwt_token_ttl%'
app / config / security.yml
# To get started with security, check out the documentation:
# https://symfony.com/doc/current/security.html
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
api_docs:
pattern: ^/doc
anonymous: true
login:
pattern: ^/api/login
stateless: true
anonymous: true
form_login:
check_path: /api/login_check
require_previous_session: false
username_parameter: username
password_parameter: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api
stateless: true
anonymous: true
lexik_jwt:
authorization_header:
enabled: true
prefix: Bearer
query_parameter:
enabled: true
name: bearer
main:
pattern: ^/
logout_on_user_change: true
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
logout: true
anonymous: true
remember_me:
secret: "%secret%" # %secret% est un paramètre de parameter
# pour que l'user restz connecté longtemps
lifetime: 31536000 # 365 days in seconds
path: /
domain: ~ # Defaults to the current domain from $_SERVER
always_remember_me: true
remember_me_parameter: _remember_me
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
# - { path: ^/, role: ROLE_USER }
- { path: ^/admin/, role: ROLE_ADMIN }
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_ANONYMOUSLY }
请帮忙吗?
已更新
我为此更改了代码:
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$chants = $em->getRepository(Chant::class)->findAll();
$data = $this->get('jms_serializer')->serialize($chants, 'json', SerializationContext::create()->setGroups(array('list')));
$response = new Response($data);
$response->headers->set('Content-Type', 'application/json');
return $response;
}
答案 0 :(得分:0)
要做的事情:
您的类应扩展FOSRestController以使用REST功能。
class ChantController extends FOSRestController
您可以像这样序列化并返回响应:
public function listAction(ParamFetcherInterface $paramFetcher, Request $request)
{
//...your code...//
$yourObjectifiedResult = $getRepository('yourentity')->findBy(['var' => $var]);
$yourNormalizedResult = $this->normalizeWithCircularHandler(
$yourObjectifiedResult,
['groups']);
//Serializer will convert your result from Object to Json Array automatically. To get a specific set of data, you can use groups.
$response = new JsonResponse(['success' => true, 'data' => $yourNormalizedResult ]);
$response->setStatusCode(Response::HTTP_OK);
return $response;
}
public function normalizeWithCircularHandler($data, $displayGroups, $normalizerCallbacks = false)
{
$encoder = new JsonEncoder();
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new ObjectNormalizer($classMetadataFactory);
$normalizer->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
if(false != $normalizerCallbacks && is_array($normalizerCallbacks)) {
$normalizer->setCallbacks($normalizerCallbacks);
}
$serializer = new Serializer([$normalizer], [$encoder]);
return $serializer->normalize($data , null, ['groups' => $displayGroups]);
}
有关序列化的信息:http://symfony.com/doc/current/components/serializer.html
有关序列化组的信息:https://symfony.com/blog/new-in-symfony-2-7-serialization-groups