- 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