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
{
"@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
{
"@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
{
"@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
{
"@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
{
"@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
{
"@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
{
"name": {
"fr-FR" : "Angleterre",
"en": "England"
}
}
=> Will create country with two localized value
OR
POST http://api.example.com/countries
{
"@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
{
"@context" : {
"@language": "it"
},
"name": "Inghilterra"
}
=> Will add or replace locale "it" name for the resource /countries/1
PUT http://api.example.com/countries/1
{
"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
{
"@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
For the "dev" part :
- create specific normalizer/denormalizer to manage @language in JSON-LD
- implements an Interface : LocalizedEntity
- Create a LocalizedResourceController to manage ?locale param and /locales endpoint