1
votes

I am modelling a REST API using RAML. The response body of an endpoint (JSON format) is a financial transactions list. Each transactions contains an amount of money: currency and numeric value. The following is the snippet of my RAML file, please note the property amount in the Transaction type:

  # %RAML 1.0
  title: Trading details API
  version: v1
  mediaType: application/json
  baseUri: http://my.host.io/api/trading/v1/
  types:
    Transactions:
      type: Transaction[]
      minItems: 1
    Transaction:
      type: object
      properties:
        refNum:
          type: string 
        amount:
          type: ????
        currency:
          type: string
          minLength: 2
          maxLength: 3

  /trades
    get:
      description: Get details for a given trade
      queryParameters:
        userId:
          type: integer
          required: true

      responses:
        200:
          body:
            application/json:
              type: Transactions

Unfortunately RAML has no Built-in decimal type, and the other numeric types (integer, float or double) are not suitable for this scope, mainly because I need to specify the number of digits after the . .

So question is: in RAML how do I correctly model the type amount?

I need to provide an exact definition of the type for each response body values, because this file will be the contract between the backend and frontend (developed by 2 different teams).

Any helps is welcomed.

Please note that I made some research on SO, and the closest question to mine is: How to define money amounts in an API . But it is not related to RAML modelling, and the answers are not helping to me.

2

2 Answers

1
votes

RAML has a similar construct to the one in JSON Schema. You'll want to use type: number in combination with multipleOf to describe decimal precision.

#%RAML 1.0 DataType

type: number
multipleOf: 0.01
0
votes

After months I come back to share my experience.

The way I worked around it was by using the type string and a pattern. I am aware of the many concerns around changing the data type from number to string, but this approach is elegant, robust, flexible and still simple to test and understand.

The API consumers are forced to format the amount in the correct way and the messages coming in and out of the API are consistent, consistency cannot be guaranteed by using multiplyOf 0.0001 (where 25 and 25.0000 are both accepted).

I reused over and over this solution with great results. Therefore I am sharing this with the community.

Solution:

   [...]
   amount:
     type: string
     pattern: "^(([1-9][0-9]*)|[0])[.]([0-9]{4})$"
     currency:
       type: string
          ...

The pattern accepts 4 digits on the decimal part, forces to use a . and the amount cannot starts with 0, with the exception of 0.xxxx family of numbers.

The following is an examples list of accepted numbers:

1.0000
54.0000
23456.1234
1.9800
0.0000
0.0001

Instead the following is an example list of rejected:

0123.3453
12.12
1.1
000
01.0000
1.0
1.00
4.000

Moreover, you can specify the max number of digits on the left side (in this example 10):

pattern: "^(([1-9][0-9]{0,9})|[0])[.]([0-9]{4})$"

Example of accepted numbers:

1234567890.1234
3.5555
0.1234

Example of rejected numbers:

12345678901.1234
123456789012.1234