8000 Unified API: JSON-LD and internationalisation · Issue #11412 · Sylius/Sylius · GitHub
[go: up one dir, main page]

Skip to content
Unified API: JSON-LD and internationalisation #11412
@pamil

Description

@pamil

What is JSON-LD?

JSON-LD stands for “JSON for Linking Data”. It’s developed by W3C and used to build interoperable Web services.

JSON-LD 1.1 provides a non-normative specification for string internationalisation.

JSON-LD is meant to be used in the server responses, providing data that can be processed and normalised with JSON-LD processor, which behaviour can be explored further using JSON-LD Playground.

How can JSON-LD be used for internationalisation?

JSON-LD internationalisation support can be applied to the whole document, or to specific fields only. JSON-LD processor will normalise both the internationalised fields and the non-internationalised fields:

  1. Field jobTitle is set to be in the en language
  2. After processing, jobTitle field is a list of maps, each map containing the information of the language and the translated value
  3. For the non-internationalised fields like name, they will be processed similarly, containing a list of maps, each map containing the value, but no language data, as it’s not specified in the context

The way JSON-LD processor works allows us to add more translations for a given field without sacrificing backwards compatibility, by using @container in the context:

  1. By setting @container as @language for jobTitle field, we tell the processor that jobTitle field will be a map, containing translated values indexed by the language.
  2. jobTitle changes its form from just a simple string in a previous example to a map mentioned above
  3. Even though jobTitle structure has changed, the processed JSON-LD returns a backwards-compatible structure. jobTitle field is still a list containing a map of the language to the translated value, but containing two elements now.

Could we apply JSON-LD i18n to the existing structure?

TL;DR: No.

Having translations as a map of languages to a map of translations is not compatible with JSON-LD specification.

jsonld3

How to determine which languages to include in the response?

To prevent overfetching, improve the performance and maintain consistent behaviour across our existing store frontend and Shop API, it is required to define a clear way to determine which languages should be included in the server response.

Some inspiration can be found in Locastic/ApiPlatformTranslationBundle and Accept-Language header spec.

I propose to use Accept-Language header and extend its usage to a GET parameter if needed. Accept-Language header accepts either a list of accepted languages or * as a wildcard for all of them:

  • If we get a single language like en - return translations only for this language
  • If we get a list like en, pl, de - return translations in those three languages OR prefer en and fallback to pl and then to de
  • If we get * - return all the possible translations

If the request is made in shop context (eg. user is not logged in / logged in as a shop user), we should filter out the list of languages using the list of languages defined on the channel, accepting only the ones existing in both of those lists.

Okay, what about requests to the server: POST/PUT/PATCH?

It’s time for things to get trickier - setting translations while adding a new translatable resource or updating one.

In the current implementation, the responses from GET requests are almost symmetrical to the payload for POST/PUT requests. If the GET response gets to conform with JSON-LD internationalisation, this would no longer be the case. However, there are two main schema designs to explore:

Translations as the main container for any translatable value

This solution is the same as the currently used - all the translatable data is stored in the translations field, all the non-translatable data is stored at the root level.

{
    "code": "JOHN_SMITH", 
    "translations": {
        "en": {
            "name": "John Smith",
            "title": "Blackmith"
        },
        "pl": {
            "name": "Jan Kowalski",
            "title": "Kowal"
        }
    }
}

Translations embedded in every translatable field

This solution is more similar to the JSON-LD one, with language maps embedded for translatable properties, next to non-translatable ones.

{
    "code": "JOHN_SMITH",
    "name": {
        "en": "John Smith",
        "pl": "Jan Kowalski"
    },
    "title": {
        "en": "Blacksmith",
        "pl": "Kowal"
    }
}

Conclusion?

Further R&D work is needed to define the input schema in our API. JSON-LD looks like a good solution for the output schema in our API.

PoC needs to be made to make sure there are no hidden blocking issues. Collaboration with the API Platform team could be a way to explore more possible solutions, as well as to get some advice regarding the implementation details.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    APIAPIs related issues and PRs.Do not staleImportant issues and PRs, that should not be stalled by Stale BotRFCDiscussions about potential changes or new features.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0