[MGNLREST-153] Retrieve one language with delivery endpoint Created: 20/Nov/17  Updated: 14/Mar/18  Resolved: 09/Feb/18

Status: Closed
Project: Magnolia REST Framework
Component/s: delivery
Affects Version/s: None
Fix Version/s: 2.1

Type: Story Priority: Major
Reporter: Christopher Zimmermann Assignee: Ngoc Nguyenthanh
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: 0d
Time Spent: 9.25d
Original Estimate: 5d

Issue Links:
Relates
relation
is related to MGNLREST-178 Attempts to request multiple language... Closed
Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Release notes required:
Yes
Documentation update required:
Yes
Date of First Response:
Epic Link: REST Phase2
Sprint: Saigon 131, Saigon 132, Saigon 133
Story Points: 8

 Description   

User story:
As a Developer, I can specify which language I want.

Capabilities:
I can include the locale in the REST request in some way to specify which language response I want.
I can request to get the response in all locales, by not requesting a specific language.

Currently, every response includes the content from all locales.

Christoph Meier was collecting ideas for localization of the JSON provided by the delivery endpoint in the context of the ideation (of PM); see Prototyping: Hybrid Headless - cmeier - the linked google doc also provides linked to earlier research done by the VN core team.



 Comments   
Comment by Ngoc Nguyenthanh [ 24/Jan/18 ]

Solution

  • Detects requested locale and select the best match in a ContainerRequestFilter which explicitly added by using HTTP header: Accept-Language
  • Creates a node wrapper allows to get appropriate data based on requested locale.
  • Applies the i18n node wrapper for the response on a ContainerResponseFilter

Behaviors:

  • Accept only supported locales specify in I18nContentSupport#getLocales
  • For un-supported locales returns data with the default locale specify I18nContentSupport#getDefaultLocale
  • Returns all of data if there is no "Accept-Language" header
  • When specify a supported locale, returns nodes and properties with data in requested locale. Nodes and properties names returns without locale suffix in its name.

Testing

  • Integration test as a whole

Agreements:

  • Don't support for an URL query parameters. See follow up ticket: TBD

Open points:

  • For now, all classes are in delivery package and dedicated for delivery endpoint. Find use cases to apply on core package.
  • Works with reference resolver.
Comment by Ngoc Nguyenthanh [ 01/Feb/18 ]

Follows the standard & best practices for Content Negotiation (http://docs.jboss.org/resteasy/docs/3.1.4.Final/userguide/html/JAX-RS_Content_Negotiation.html), supporting request language in query parameter of the URL is not a good option (excepts : Query String Parameter-based negotiation )
However, as an end-user, it provides convenience when working with REST API, especially via browser address.
I've decided to support the "lang" query parameter.
Behaviors work as bellow:

No Accept-Language header + NO lang query parameter

  • Returns data with locale provided by 18nContentSupport#getLocale

Has Accept-Language header + Has lang query parameter

  • lang query parameter will get higher priority when parsing.

Has Accept-Language header + NO lang query parameter

  • Using Server Content Negotiation algorithm to select the best match from the Accept-Language header
  • Should be a supported languages. See I18nContentSupport#getLocales
  • Accept-Language specification - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language.
    • Any language; '*' is used as a wildcard: It doesn't mean that we'll return all languages. It means that it accepts any language the sever returns.
    • Multiple types, weighted with the quality value syntax: Accept-Language: fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5. It means that we'll select the best match of supported languages with respecting of weight.
    • We don't support multiple languages. Very rare cases that an user need to request multiple languages in one request. If you want to support it anyway, a follow up ticket should be created. Additional, Magnolia's current implementation of I18nContentSupport doesn't support multiple languages as well.

NO Accept-Language header + Has lang query parameter

  • Parsing language tag from the "lang" query parameter which is specified in the URL.
  • In case of it's a full language tag (de-CH, en-US, etc) and the system doesn't have any locale match perfectly the request. Then selects the closest supported locale (Eg: de, en, etc). See AbstractI18nContentSupport#getNextLocale
  • Use "lang=all" when you want to return data without i18n affected.

See the integration tests for more cases - info.magnolia.integrationtests.rest.delivery.jcr.v2.I18nDeliveryEndpointTest

Comment by Christopher Zimmermann [ 01/Feb/18 ]

Sounds good.
Im still concerned/uncertain about behaviour when "No Accept-Language header + NO lang query parameter". I guess this would be the case when requesting from another server (node etc) or a proxy. (Not sure if requests from mobile apps or desktoip apps would have the Accept-Language header?) I think most devs would expect to get the default language only. That's how the web-pages work, delivering default language when no language is specified.

I know its not backwards compatible, but developers will anyways be actively selecting the new version of the delivery class to get these new features - won't they? In which case it does not need to be backwards compatible.

Comment by Ngoc Nguyenthanh [ 01/Feb/18 ]

czimmermann Agree, it's common sense. Because of we're only apply this feature on Delivery endpoint version 2, then back-compatibility is not an issue I guess.
So that, as your wish, I'll return the default language which is returned by I18nContentSupport.
Besides that, we'll need to support an option to return all languages. As I've mentioned above, "*" in "Accept-Language" doesn't prefer to all languages, any language instead. So that in order to return all languages, the only solution is use the "lang" query parameter.
I'm wondering of 2 options: lang=* and lang=all. Because of '' will make user confuse when using "Accept-Language", I'd prefer the option: "lang=all", it's more clear.
What is your suggestion?

Comment by Christopher Zimmermann [ 01/Feb/18 ]

I like the lang=all approach for the reasons that you mention.

Comment by Ngoc Nguyenthanh [ 06/Feb/18 ]

I've updated the current behavior in the comment above.
One thing need to be emphasized is: Our implementation is only support data (node, property) with the pattern "name_locale" which is the current implementation of Magnolia.
Regarding HierarchyBasedI18nContentSupport: still able to be affected when using read node endpoint without any explicitly language request.
Basically, when we can't determine the locale from the request by "lang" parameter or "Accept-Language" header, we will let the i18nContentSupport decide the locale. And for sure, there is always have a fallback language.
See https://documentation.magnolia-cms.com/display/DOCS56/AdminCentral+and+public+locales

Generated at Mon Feb 12 06:57:08 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.