Problem/Motivation

The JSON:API client can only target a translation through a /{locale}/ URL path prefix. That works for a stock multilingual site using URL language negotiation. Sites using the JSON:API Multilingual module select the translation on the canonical URL via a langCode query parameter that is not dependent on the site's language negotiation settings.

Proposed resolution

  1. Reads send the language as a langCode query parameter and, for backwards compatibility with URL-prefix negotiation, as the /{locale}/ path prefix. Stock backends ignore the parameter (a spec-valid implementation-specific query parameter) and negotiate by prefix; backends using jsonapi_multilingual select the translation with the parameter alone, so the same request works on either backend. With the module, a read of a translation that does not exist is a strict 404 (individual) or excludes the item (collection, reported under meta.omitted).
  2. A new includeFallback read option sends includeFallback=1, deferring a missing translation to the site's language fallback chain instead of failing strictly: an individual read of existing content always resolves, and a collection includes every item in its best available language. Ignored by stock backends.
  3. A new instance option languagePathPrefix: false allows dropping the prefix entirely (including from collection POSTs and the decoupled_router hop of getResourceByPath). Recommended for backends using jsonapi_multilingual, where the langCode query parameter carries the language; required for backends that do not serve /{locale}/ URLs.
  4. Writes target exactly one translation: updateResource / deleteResource send the prefix plus a langCode query parameter.
  5. A new createTranslation() method adds a translation to an existing entity via an individual-path POST.
  6. A new getAvailableTranslations() helper extracts the meta.availableTranslations langcodes that a strict backend's 404 advertises, for retrying with an existing language or rendering a language switcher.
  7. getResourceByPath() uses the resolved translation's language (the entity.langcode that jsonapi_multilingual adds to translate-path responses) as the follow-up read's locale when the caller does not pass one, so translated aliases return the translation they name.

Remaining tasks

User interface changes

API changes

API changes explained in Proposed resolution, changes are fully backwards compatible.

Data model changes

Issue fork api_client-3612682

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

lauriii created an issue. See original summary.

lauriii’s picture

Issue summary: View changes
brianperry’s picture

Status: Active » Fixed

Merged and published on npm. Thanks again @lauriii and @mglaman!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.