Upgrade to Pro — share decks privately, control downloads, hide ads and more …

循環参照してるEntityのシリアライズとかの話

Takashi Kanemoto
July 08, 2018
640

 循環参照してるEntityのシリアライズとかの話

Symfony Meetup #21 LT 資料
https://symfony.connpass.com/event/90319/

Takashi Kanemoto

July 08, 2018
Tweet

Transcript

  1. ͋͞ɺ͋ͳͨ΋ࠓ͙͢ϑΥϩʔ͠Α͏!!! ׬શແྉ ͨ ͭ ͖ ͪ twitter.com/ttskch ·͞ʹ໊ݴ੡଄ػ ਓੜͰେ੾ͳ͜ͱ͸ɺ͢΂ͯ ͖͔ͨͭͪΒڭΘͬͨ

    ͖ͨͭͪΛϑΥϩʔͨ͠Β
 ࠊ௧͕࣏Γ·ͨ͠  ͍ͯ͠Δ ͍ͯ͠ͳ͍ ͖ͨͭͪΛϑΥϩʔ͍ͯ͠Δʁ ϑΥϩϫʔ͞Μ100ਓʹฉ͖·ͨ͠ 100% φϯτʂ ϑΥϩϫʔ͔Βͷࢧ࣋཰ 3/30
  2. class User { public $name; /** * @var Post[] */

    public $posts; } 8 Α͋͘Δ User(1) - Post(N) class Post { public $title; /** * @var User */ public $user; } /30
  3. { "name": "user1", "posts": [ { "title": "post1" }, {

    "title": "post2" } ] } 10 ݁Ռ posts.user͕ফ͑ڈͬͯΔ /30
  4. class User { public $name; /** * @var Post[] */

    public $posts; } 11 user.posts.user = userʢ॥؀ࢀরʣ class Post { public $title; /** * @var User */ public $user; } /30
  5. use JMS\Serializer\Annotation\MaxDepth; class User { public $name; /** * @var

    Post[] * * @MaxDepth(1) */ public $posts; } 13 ΍ͬͯΈͨ /30
  6. - $serializer = SerializerBuilder::create()->build(); + $serializer = SerializerBuilder::create() + ->setSerializationContextFactory(function

    () { + return SerializationContext::create() + ->enableMaxDepthChecks() + ; + }) + ->build() + ; 14 ΍ͬͯΈͨ MaxDepthͷνΣοΫΛ༗ޮԽ /30
  7. { "name": "user1", "posts": [ { "title": "post1" }, {

    "title": "post2" } ] } 15 ݁Ռ มΘΒͣɻ /30
  8. if ((null === $v && $context->shouldSerializeNull() !== true) || (true

    === $metadata->skipWhenEmpty && ($v instanceof \ArrayObject || \is_array($v)) && 0 === count($v)) ) { return; } 17 JsonSerializationVisitor.php ͜͜Ͱreturnͯͨ͠ʢ஋͕null͔ͭɺnull͸γϦΞϥΠζ͠ͳ͍ઃఆʣ /30
  9. { "name": "user1", "posts": [ { "title": "post1", "user": null

    }, { "title": "post2", "user": null } ] } 19 ֬ೝ post.user͸͔֬ʹnullʹͳͬͯΔ /30
  10. foreach ($user->posts as $post) { $post->user = clone $user; }

    $json = $serializer->serialize($user, 'json'); 23 clone $user ͯ͠ஔ͖׵͑ͯΈΔ /30
  11. { "name": "user1", "posts": [ { "title": "post1", "user": {

    "name": "user1", "posts": [ null, null ] } }, : ] } 24 ݁Ռ ͳΔ΄Ͳߦ͚ͨɻ /30
  12. APIΛ෼͚Δ 27 • userͱposts͸ผʑͷAPI͔Βऔಘ͢Δ • ϑϩϯτͷΠϝʔδ http.get(`/users/${user.id}`) .then(user => http.get(`/users/${user.id}/posts`)

    .then(posts => ({user, posts}))) .then(({user, posts}) => { user.posts = posts; this.user = user; }) ; /30
  13. // user-repository.ts get(id: string): Observable<User> { return this.http.get(`/users/${id}`).pipe( map(response =>

    getUserFromResponse(response)), switchMap((user: User) => this.postRepository.cgetByUser(user).pipe( map((posts: Post[]) => { user.posts = posts; return user; }) )) ); } 28 Angular (rxjs@6) ͩͱ͜Μͳײ͡ /30