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.
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