I always found that globalization is the poor child of computer literature. In any .NET book, you won’t hear specifically about globalization before chapter 23. You can even tell it’s not shooting high on the radar when you look at the ways globalization was implemented in the three main front-end Frameworks of .NET: WinForm (great!), ASP.NET (retrofitted in sub-optimal way in .NET 2.0) & WPF (totally Byzantine and not even in line with the rest of .NET Framework).
Since I work in Montreal –a bilingual city in a bilingual country– I’m confronted to globalization on nearly every projects I’m involved in. So with time you do build up your bag of tricks & patterns around globalization.
I recently posted a blog talking about the W3C globalization specs for SOAP endpoints, WS-I18N. I found that spec quite interesting because it describes a standard way to handle globalization at a web service level.
Actually, the most common approach I’ve seen (or architected myself) with globalization & web services is to not localize it. For the time zone, you can usually get away by returning time in standard GMT and let the client localize it. For languages, if your application is only bilingual (as is often the case in Canada), you can get away by returning the localized data in both languages since you will typically have properties such as FrenchTitle & EnglishTitle in your data contracts.
This approach has a lot of advantages. First is simplicity of course. But you also get other advantages. For instance, if your application needs to flick between languages in a real-time fashion, with this approach you do not need to interrogate web services again (and potentially get different data, which would make the change language feature a refresh feature at the same time, which is weird). It’s also easier to implement caching if you do not have out-of-band parameters also.
Sometimes you won’t have that luxury. For instance, the project I’m currently working on is multi-lingual in the sense the number of supported cultures is open. We therefore have to model our database with localized value in a vertical way (one row per culture). For the services we were still lucky. The only localized values are list of values (lookups) ; for those we manage them explicitly in the respective service. The other services aren’t localized: the content is in the language the user punched it in. Also, we raise SOAP faults with English-message. The architecture guideline there is that the services aren’t producing user-messages, they are APIs, they can raise faults, but it’s up to the application to interpret the fault and inform the user accordingly.
I think it’s important to think about the role of your services in your application, system, enterprise or context in general. If it’s an API for smart applications to use, I would really aim at not localizing them. This way you can rip the benefit of simplicity but also, you won’t get into confusion of an application being in culture X calling services in culture Y. If your services are meant to be use by themselves or by thin applications (e.g. something doing an xslt-transform on the data returned by your services), you should manage the culture at the service layer.