Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support registering serializers / deserializers for Dexterity Schemas #1832

Open
ericof opened this issue Oct 31, 2024 · 3 comments
Open

Support registering serializers / deserializers for Dexterity Schemas #1832

ericof opened this issue Oct 31, 2024 · 3 comments
Assignees

Comments

@ericof
Copy link
Member

ericof commented Oct 31, 2024

Problems to be solved

  • Remove code duplication for schema serialization (dxcontent.py and site.py)
  • Allow custom serialization of specific behaviors.
    • A use case would be to serialize a behavior in a different way if the user does not have a specific permission, i.e. masking the data if the user is not allowed to edit the content.

Example implementation

New Serializer Interface

Register serializers against a new interface

class ISchemaSerializer(Interface):
    """The field serializer multi adapter serializes the field value into
    JSON compatible python data.
    """

    def __init__(schema, context, request):
        """Adapts schema, context and request."""

    def __call__():
        """Returns JSON compatible python data."""

Register new serializers against this interface

@implementer(ISchemaSerializer)
@adapter(IInterface, IDexterityContent, Interface)
class SerializeSchemaToJson:
    """Serialize a schema to JSON."""

Function to serialize all schemata

def serialize_schemas(context: DexterityContent, request: HTTPRequest) -> dict:
    result = {}
    for schema in iterSchemata(context):
        serializer = queryMultiAdapter((schema, context, request), ISchemaSerializer)
        result.update(serializer())
    return result

Refactor dxcontent.py and site.py to use new helper function

        # Insert field values
        result.update(serialize_schemas(obj, self.request))
@ericof ericof self-assigned this Oct 31, 2024
@davisagli
Copy link
Member

@ericof Could you explain the use case please?

@davisagli
Copy link
Member

@ericof I'm not convinced yet.

Remove code duplication for schema serialization (dxcontent.py and site.py)

I'm not that worried about the duplication, because we should be able to remove it once we drop support for Plone 5

Allow custom serialization of specific behaviors.
A use case would be to serialize a behavior in a different way if the user does not have a specific permission, i.e. masking the data if the user is not allowed to edit the content.

This is already supported by configuring a read_permission for the field, isn't it?

I also don't want to add a new extension mechanism for serialization without also thinking about how it interacts with deserialization. In general when editing the serialized content goes in the redux store in Volto, gets updated, then sent back to the server. So if it's serialized in some unusual format, there needs to be a way to handle it during deserialization as well.

@ericof
Copy link
Member Author

ericof commented Nov 1, 2024

Remove code duplication for schema serialization (dxcontent.py and site.py)

I'm not that worried about the duplication, because we should be able to remove it once we drop support for Plone 5

Good point.

Allow custom serialization of specific behaviors.
A use case would be to serialize a behavior in a different way if the user does not have a specific permission, i.e. masking the data if the user is not allowed to edit the content.

This is already supported by configuring a read_permission for the field, isn't it?

No, read_permission is all or nothing, if you don't have it, it won't be serialized. What I need is something "gray".
Imagine you have a behavior with a SSN field. If you are able to edit that field, you see the value, otherwise you will see a masked version of this number. (Useful for egov sites where you want to expose data, but to a certain level.)

Also, if I want to add additional information to a behavior serialization, but I don't want to touch the Field serializer, this is useful.
In a conference site, I have a behavior with session information that is used my multiple content types. I want to "enrich" the serialization of this behavior by always adding a new key with schema.org metadata to be used. This is meant to be read-only, but added to the serialization of types that use this behavior.

A third use case , that ties to your point bellow, is to write serializers (and deserializers) to group information under a key. For instance, I want all data for my behavior (contact.address) to be grouped under the same key. And then, during the deserialization be exposed again as their own attributes.

I also don't want to add a new extension mechanism for serialization without also thinking about how it interacts with deserialization. In general when editing the serialized content goes in the redux store in Volto, gets updated, then sent back to the server. So if it's serialized in some unusual format, there needs to be a way to handle it during deserialization as well.

Already implementing this support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants