-->

JMS Serializer serialize object in object with dif

2019-06-02 05:54发布

问题:

I'm developing a RESTful service with Symfony2, JMS Serializer Bundle, FOS Rest Bundle and Hateoas Bundle. There are 2 entities User and Company and I want to, when I serialize a Company get larger detail. But, when serializing User related Company show only Company ID and name object or just ID as integer.

I have serialize policy like below.

User

Acme\UserBundle\Entity\User:
exclusion_policy: ALL
xml_root_name: user
properties:
    id:
        expose: true
        type: integer
    company:
        expose: true
        type: Acme\CompanyBundle\Entity\Company
    name:
        expose: true
        type: string
    surname:
        expose: true
        type: string
    picture:
        expose: true
        type: string
relations:
    -
        rel: self
        href:
            route: acme_v1_get_user
            parameters:
                id: expr(object.getId())
            absolute: true

Company

Acme\CompanyBundle\Entity\Company:
exclusion_policy: ALL
xml_root_name: company
properties:
    id:
        expose: true
        type: integer
    name:
        expose: true
        type: string
    address:
        expose: true
        type: string
    phone:
        expose: true
        type: string
    web:
        expose: true
        type: string
    created_date:
        expose: true
        type: DateTime
    updated_date:
        expose: true
        type: DateTime
    status:
        expose: true
        type: integer
relations:
    -
        rel: self
        href:
            route: acme_v1_get_company
            parameters:
                id: expr(object.getId())
            absolute: true

Expected output

{
  "id": 1,
  "name": "Jenny",
  "surname": "Doe",
  "picture": "http://google.com/kittens.jpg",
  "info": [],
  "company": {
    "id": 1,
    "name": "Demo Company"
  }
}

OR

{
  "id": 1,
  "name": "Jenny",
  "surname": "Doe",
  "picture": "http://google.com/kittens.jpg",
  "info": [],
  "company": 1
}

What I got

{
  "id": 1,
  "name": "Jenny",
  "surname": "Doe",
  "picture": "http://google.com/kittens.jpg",
  "info": [],
  "company": {
    "id": 1,
    "name": "Demo Company",
    "address": "Lorem ipsum dolor sit amet",
    "phone": "0902124440444",
    "web": "http://www.demo-company.com",
    "created_date": "2015-07-22T11:21:03+0300",
    "updated_date": "2015-07-24T01:50:39+0300",
    "status": 1
  }
}

回答1:

You can use groups

AppBundle\Entity\User\User:
    exclusion_policy: ALL
    properties:
        lastname:
            expose: true
            groups: [info]

And with an annotation, you can define which property is displayed on which group. And finally, you can assign a group to every route you use.

Or you can use virtual properties like so :

AppBundle\Entity\User\User:
    exclusion_policy: ALL
    properties:
         […]
    virtual_properties:
        getCompanyId:
            serialized_name: company
            type: string
            groups: [info]

And you create a getCompanyId() method in your User entity, that returns the companyId



回答2:

The more Hateoas way to do it would be with the relations.

Acme\UserBundle\Entity\User:
exclusion_policy: ALL
xml_root_name: user
properties:
    id:
        expose: true
        type: integer
    name:
        expose: true
        type: string
    surname:
        expose: true
        type: string
    picture:
        expose: true
        type: string
relations:
    -
        rel: self
        href:
            route: acme_v1_get_user
            parameters:
                id: expr(object.getId())
            absolute: true
    -
        rel: company
        href:
            route: acme_v1_get_company
            parameters:
                id: expr(object.getCompany().getId())
            absolute: true

Would yield...

{
  "id": 1,
  "name": "Jenny",
  "surname": "Doe",
  "picture": "http://google.com/kittens.jpg",
  "info": []
  "_links": {
    "self": {
      "href": "http://server.com/api/user/1"
    },
    "company": {
      "href": "http://server.com/api/company/1"
    },
  }
}