2

I am setting up an event calendaring site that needs to store venue addresses. Street/postal addresses rather than email or IP or any other addresses.

As I would like my site to work internationally, I would like to have sufficient and correct address fields to cover all possible/reasonable addresses. I have previously been using a block of text as I didn't need access to the individual fields but now I would like to be able to extract the town/city from each address so storing as more specific fields seems sensible.

Question: Is there a recognised set of fields for storing international postal/street addresses? Or is it country specific?

Schema.org's PostalAddress format might indicate one example.

  • Even though you say "storing", you seem to be asking about displaying addresses. Schema.org is the de-facto method to structure a displayed address. It is indeed international (they use "region" and "postalcode"). You can take it a bit further by naming your input fields the same a la <input name="postalCode" />. As far as storing the data, it's a DB thing and you can name those fields whatever you like (since nothing sees it besides you app(s)). – dhaupin Nov 17 '14 at 14:29
  • Thanks for the comment, what I mean is that are the fields used by Schema.org optimal and sufficient for all international addresses? I realise they are quite generic. I would like to have users input addresses in a manner that I can store & extract country & city at very least. I was wondering if different countries have different different conventions for how they write addresses? – MichaelJones Nov 17 '14 at 16:37
1

This has been asked and answered on StackOverflow. Here is Nicholas Piasecki's excellent and highly upvoted answer.


I've been thinking about this myself as well. Here are my loose thoughts so far, and I'm wondering what other people think.

xAL (and its sister that includes personal names, XNAL) is used by both Google and Yahoo's geocoding services, giving it some weight. But since the same address can be described in xAL in many different ways--some more specific than others--then I don't see how xAL itself is an acceptable format for data storage. Some of its field names could be used, however, but in reality the only basic format that can be used among the 16 countries that my company ships to is the following:


enum address-fields 
{
    name,
    company-name,
    street-lines[], // up to 4 free-type street lines
    county/sublocality,
    city/town/district,
    state/province/region/territory,
    postal-code,
    country
}

That's easy enough to map into a single database table, just allowing for NULLs on most of the columns. And it seems that this is how Amazon and a lot of organizations actually store address data. So the question that remains is how should I model this in an object model that is easily used by programmers and by any GUI code. Do we have a base Address type with subclasses for each type of address, such as AmericanAddress, CanadianAddress, GermanAddress, and so forth? Each of these address types would know how to format themselves and optionally would know a little bit about the validation of the fields.

They could also return some type of metadata about each of the fields, such as the following pseudocode data structure:


structure address-field-metadata 
{
    field-number,     // corresponds to the enumeration above
    field-index,      // the order in which the field is usually displayed
    field-name,       // a "localized" name; US == "State", CA == "Province", etc
    is-applicable,    // whether or not the field is even looked at / valid
    is-required,      // whether or not the field is required
    validation-regex, // an optional regex to apply against the field
    allowed-values[]  // an optional array of specific values the field can be set to
}

In fact, instead of having individual address objects for each country, we could take the slightly less object-oriented approach of having an Address object that eschews .NET properties and uses an AddressStrategy to determine formatting and validation rules:


object address
{
    set-field(field-number, field-value),
    address-strategy
}

object address-strategy
{
    validate-field(field-number, field-value),
    cleanse-address(address),
    format-address(address, formatting-options)
}

When setting a field, that Address object would invoke the appropriate method on its internal AddressStrategy object.

The reason for using a SetField() method approach rather than properties with getters and setters is so that it is easier for code to actually set these fields in a generic way without resorting to reflection or switch statements.

You can imagine the process going something like this:

  1. GUI code calls a factory method or some such to create an address based on a country. (The country dropdown, then, is the first thing that the customer selects, or has a good guess pre-selected for them based on culture info or IP address.)
  2. GUI calls address.GetMetadata() or a similar method and receives a list of the AddressFieldMetadata structures as described above. It can use this metadata to determine what fields to display (ignoring those with is-applicable set to false), what to label those fields (using the field-name member), display those fields in a particular order, and perform cursory, presentation-level validation on that data (using the is-required, validation-regex, and allowed-values members).
  3. GUI calls the address.SetField() method using the field-number (which corresponds to the enumeration above) and its given values. The Address object or its strategy can then perform some advanced address validation on those fields, invoke address cleaners, etc.

There could be slight variations on the above if we want to make the Address object itself behave like an immutable object once it is created. (Which I will probably try to do, since the Address object is really more like a data structure, and probably will never have any true behavior associated with itself.)

Does any of this make sense? Am I straying too far off of the OOP path? To me, this represents a pretty sensible compromise between being so abstract that implementation is nigh-impossible (xAL) versus being strictly US-biased.


Update 2 years later: I eventually ended up with a system similar to this and wrote about it at my bliggity blog: http://nicholas.piasecki.name/blog/2010/11/inside-skiviez-mailing-addresses/

I feel like this solution is the right balance between legacy data and relational data storage, at least for the e-commerce world.

  • Very interesting! Thank you. I actually didn't check Stackoverflow as I thought best practice questions were closed there. Thanks for sharing it. – MichaelJones Nov 18 '14 at 13:34
  • It probably would be closed there if asked today. It's good to have these questions here where they are more on-topic. – Stephen Ostermiller Nov 18 '14 at 13:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.