Skip to content

Custom Serialization Groups & Access To Root Entity Class On Normalization #283

@kiler129

Description

@kiler129
  • Symfony version: 4.2.1
  • Algolia Search Bundle version: 3.4.0
  • Algolia Client Version: 1.28.0
  • Language Version: 7.3.1

Description

Currently normalizers are called with a special searchableArray format. However this is still not enough, since you can only determine if the data is serialized for Algolia or for different purpose (e.g. API-Platform). There's no way (or I don't see it) to support such structure:

[books_index] (e.g. for autocomplete) | - book1 | | - title: Foo Bar | | - author: John Doe | \ - readers: 124 \ - book2 | - title: Baz Bat | - author: Josh A. \ - readers: 222 [categories] | - category1 | - name: Good Books \ - promoted | - book1 | | - title: Foo Bar | \ - author: John Doe \ - book2 | - title: Baz Bat \ - author: Josh A. 

This is a synthetic example, but the problem has a real business use-case. If you have collection of items you cannot get a basic version of an entity for collections and advanced version of the same entity for a separate index.

This is kind of related to #139, but I basically need to differentiate between nested objects and top level indexes.

Solutions

I see two ways of making this experience better - first is intermittent but very simple and second is advanced but flexible and easily extensible:

Pass index entity in context

normalize() receives $context array. In this array we can add class name of the currently processed index. With such construction normalize() method may look like:

 public function normalize($object, $format = null, array $context = []) { $result = $this->normalizer->normalize($object, $format, $context); if ($context['rootEntity'] === Book::class) { $result['readers'] = $this->doSomeExpensiveCalculations(); } //... }

(of course properly it should be a separate normalizer which delegates via composition etc but I skipped this for simplicity)

This can be added literally in 5 minutes (let me know - I can submit PR) by modifying SearchableEntity::getSearchableArray() to call $context['rootEntity'] = \get_class($this->entity).

Allow defining normalization groups

This is a proper solution for the problem. Currently there's a blanket searchable group passed. This is good when I want to decide what goes to search engine and what not, however I cannot have multiple groups depending on the index.

This could be defined as follow:

algolia_search: indices: - name: books class: ACME\Entity\Book enable_serializer_groups: true serializer_groups: - searchable - searchableMainBookRoot - name: categories class: ACME\Entity\Category enable_serializer_groups: true serializer_groups: - searchable - searchableMainBookChild

Implementing this will require plugging into SearchableEntity::getSearchableArray() and changing how configuration is parsed to get this extra list. All in all it doesn't seem like a lot more work.

Conclusion

RFC ;) Maybe I don't understand something, but I think in a current state what I need is not possible.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions