Conditional Type


#1

Very new to RAML and API design.

Basically I need to design an API that works for different location and will return data dependent on the location…

I would like to be able to return a US address if I hit /addresses/US but a French address if I hit /addresses/FR

Is there a way I can have a generic path like:
/addresses/{countryCode}: type: {Member: {item : AddressTypes.{countryCode}_address } }

Or do I have to define the different ones like:
/addresses/US: type: {Member: {item : AddressTypes.US_address } }
/addresses/FR: type: {Member: {item : AddressTypes.FR_address } }

Second one will lead to a lot of repeating code…

Any pointers are appreciated!

Thanks!


#2

The first is correct, you use {path-param} and then define the type of param it is. The examples will show you how this works quite well. Defined something like:

/addresses/{country-name}:
displayName: AddressesByCountryName
uriParameters:
country-name:
displayName: CountryName
type: string
required: true
description: The name of the country to return the response for

How are you using RAML? Are you generating code from it, or only using it to document your API?

RAML2HTML will soon have RAML 1.0 support, pretty close now, and does a pretty good job of documenting nicely. You may also like the RAML2JAXRS project if you are looking to use RAML as a single source of truth for your API in which case this would generate server side JAXRS (for Java) that matches the API definition, making it easy to keep your code, documentation, etc in sync with your defined API contract.


#3

Hi Kevin_Duffey

Thanks for your answer.

I’m using it for documenting APIs.

We’re currently using a 3rd party for most of our development work and I would really like to get better control of the API layer. Right now it’s the fox guarding the henhouse…

It would be really great to do some mocking of the APIs and actually validate the APIs. That way we can use this more as a spec.

I’m not seeing how the example you have actually help me. (you have type: string for country-name.)

The address types I have are AddressTypes.US_Address and AddressTypes.UK_Address for example. These types have different members. E.g. US has zipCode, UK has postalCode.

How can I use the {country-name} to select the correct address type?

I would like to have the type be some sort of variable so that I can do something like this:
type: AddressTypes.{country-name}_Address

Thanks!


#4

If I understand you correctly, you are trying to define a dynamic type that will take into account the name on the URL path passed in. As far as I know this is beyond the capability of the spec itself. This would be an implementation detail. You can easily fashion a response type that your implementation then fills in with the required response type you need, e.g. it can take from the URL path the {country-name} and return that… but you would have to implement that. The spec is to define the API, not necessarily to add functionality in some manner. You can, however, add annotations that can then be used by a parser aware of such annotations to provide special needs in some manner, but this would be completely custom/proprietary for your own use and still would rely on you being able to parse the RAML doc and look for custom annotations, then add some code to handle the logic behind what the annotation is meant to do.


#5

Hi Kevin_Duffy

This seems to take care of what I want:

From AddressTypes:

types:
  Address: UK_Address | FR_Address | US_Address
  
  UK_Address:
    properties:
    ...

  FR_Address:
    properties:
    ...

They I can use this like:

/{country-name}/addresses/:
  type:  { Collection: {item : AddressTypes.Address } }