- From: Mikael Labrut <mlabrut@lafourchette.com>
- Date: Fri, 19 Jun 2015 14:50:14 +0200
- To: public-hydra@w3.org
- Message-ID: <CAK2GM_mXVNqpn83Ttqybk0UXXSdLWxFjPaLXyGvc-EnEKTo7Zg@mail.gmail.com>
Hi, My name is Mikaël Labrut, I am actually working on an API using Hydra using DunglasApiBundle. This is great but, but one of my question have no "normalized" answer : i18n. Here is a copy of this topic ( https://github.com/dunglas/DunglasApiBundle/issues/127), we want to have a lot of opinion about this topic before implementing a solution. Feel free to say what do you think about that and what is the best way ?? Problem : Imagine you have a "Country" (http://schema.org/Country) resource in your API. How to manage i18N on it ? Here is a detailed solution, i have design based on experience, and the JSON-LD spec. Tell me if you think this is a good idea ? If you think it's not ... tell me why ? ## How to get a specific locale on a resource ? (=GET) ### My solution Add a GET specific parameter "locale" Why ? - Simple (this is the way used in FB graph api for example) - One URL = One localized resource (like wikipedia, better for indexing or caching) - use of @language specified in JSON-LD spec - use @container:@language ### Sample 1 : No locale specified GET http://api.example.com/countries/1 ```json { "@context": { "@base" : "http://schema.org", "name" : { "@container": "@language" } }, "@type": "Country", "@id": "/countries/1", "name": { "fr-FR" : "Angleterre", "en" : "England" } } ``` => Will return resource with all locale data ### Sample 2 : Use specific localization GET http://api.example.com/countries/1?locale=fr-FR ```json { "@context": "http://schema.org", "@type": "Country", "@id": "/countries/1", "@language": "fr-FR", "name": "Angleterre" } ``` => Will return resource with requested locale Note we use locale (on request + response) in W3C format (IETF's BCP 47), see http://www.w3.org/International/articles/language-tags/ It's the format used also with JSON-LD. ### Sample 3 : Error localization don't exist GET http://api.example.com/countries/1?locale=es-CA ```json { "@context": "/contexts/LocalizationError", "@type": "LocalizationError", "hydra:title": "An error occurred", "hydra:description": "no localization found for locale es-CA" } ``` => Will return code "404 not found", because es-CA localization don't exist in my api. ## How to get a specific locale on a list of resource ? (=GET) ### My solution : same as for one resource ### Sample 1 : No locale specified GET http://api.example.com/countries ```json { "@context": { "@base" : "http://schema.org", "name" : { "@container": "@language" } }, "@id": "/countries", "@type": "hydra:PagedCollection", "hydra:totalItems": 1, "hydra:itemsPerPage": 3, "hydra:firstPage": "/countries", "hydra:lastPage": "/countries", "hydra:member": [ { "@type": "Country", "@id": "/countries/1", "name": { "fr-FR" : "Angleterre", "en" : "England" } } ] } ``` => Will return resources with all available localization ### Sample 2 : Use specific localization GET http://api.example.com/countries?locale=fr-FR ```json { "@context": "http://schema.org", "@id": "/countries", "@type": "hydra:PagedCollection", "@language": "fr-FR", "hydra:totalItems": 1, "hydra:itemsPerPage": 3, "hydra:firstPage": "/countries", "hydra:lastPage": "/countries", "hydra:member": [ { "@type": "Country", "@id": "/countries/1", "name": "Angleterre" } ] } ``` => Will return resource with requested locale ### Sample 3 : Error localization don't exist GET http://api.example.com/countries?locale=es-CA ```json { "@context": "http://schema.org", "@id": "/countries", "@type": "hydra:PagedCollection", "@language": "es-CA", "hydra:totalItems": 0, "hydra:itemsPerPage": 3, "hydra:firstPage": "/countries", "hydra:lastPage": "/countries", "hydra:member": [] } ``` ## How to delete a localized resource ? (=DELETE) ### My solution : same as usual but the localization are also deleted completely DELETE http://api.example.com/countries/1 => Will delete country and all associed localization DELETE http://api.example.com/countries/1?locale=fr-FR => Will delete country localization fr-FR only ! ## How to create a localized resource ? (POST) ### My solution : create with a locale container or indicate the language in context POST http://api.example.com/countries ```json { "name": { "fr-FR" : "Angleterre", "en": "England" } } ``` => Will create country with two localized value OR POST http://api.example.com/countries ```json { "@context": { "@language": "fr-FR" }, "name": "Angleterre" } ``` => Will create country with one localized value ## How to add a new locale to a localized resource ? (PUT) ### My solution : same as POST, you must specified @language or put all localized data PUT http://api.example.com/countries/1 ```json { "@context" : { "@language": "it" }, "name": "Inghilterra" } ``` => Will add or replace locale "it" name for the resource /countries/1 PUT http://api.example.com/countries/1 ```json { "name": { "fr" : "Angleterre" } } ``` => Will delete all localization for name and just have fr localization ## How to list all available locale for a resource ? ### My solution : add a specific endpoint to api like : GET http://api.example.com/countries/1/locales ```json { "@context": "http://schema.org", "@id": "/http://api.example.com/countries/1/locales", "@type": "hydra:PagedCollection", "hydra:totalItems": 2, "hydra:itemsPerPage": 3, "hydra:firstPage": "/countries", "hydra:lastPage": "/countries", "hydra:member": [ { "@type": "Locale", "@id": "/locale/fr" }, { "@type": "Locale", "@id": "/locale/en" } ] } ``` => Will return all available locale for the resource ## Another way : separate localized content / resource I study another possibility to provide the i18n support on a resource. To add a collection of translation when needed. For example : GET http://api.example.com/countries/1?locale=fr-FR ```json { "@context": "http://schema.org", "@type": "Country", "@id": "/countries/1", "@language": "fr-FR", "nonLocalizedAttribute": 10, "localization": { "@type": "CountryLocalization", "@id": "/country_localization/1/fr-FR", "name": "Angleterre" } } ``` GET http://api.example.com/countries/1 ```json { "@context": "http://schema.org", "@type": "Country", "@id": "/countries/1", "nonLocalizedAttribute": 10, "localizations":{ "en": { "@type": "CountryLocalization", "@id": "/country_localization/1/fr-FR", "name": "Angleterre" }, "fr-FR": { "@type": "CountryLocalization", "@id": "/country_localization/1/fr-FR", "name": "England" } } } ``` This way he simpler for many reasons, but I think it's not very JSON-LD / Hydra compliant. It's simpler because : * you cut the "localized" part of the resource into separate resource, wich can be managed like other resources. * "Like the DB storage" It's not JSON-LD / Hydra compliant because : * you change structure of object ( localization / localizations attribute is dynamical ... ), you cannot use schema.org vocabulary because of that What do you think about this ? Best regards, -- Mikaël Labrut - Team B2B Github : MLKiiwy
Received on Friday, 19 June 2015 13:55:22 UTC