-
Notifications
You must be signed in to change notification settings - Fork 0
2. Structuring and Retrieving Data
Dragonfruit translates JSON data into models which can be accessed by API endpoints and filtered by queries. Models and queries are stored in the larger Swagger specification that Dragonfruit generates.
The structure of your data governs both the structure of the APIs and the available queries.
Property names in your sample data will become the property names in the Swagger model. Query parameters are similarly named after the property they query. So, this sample data:
{
"numField": 1,
"textField": "some text"
}
would by queryable like this
http://your.api/api/resource/?numField=1&textField=some%20text
This section is a bit long, so we've added a table of contents:
Here's a quick summary of how Dragonfruit translates JSON data to datapoints in your model and into queries:
JSON Data Type | Example | Model Type | Model Format | Queries |
---|---|---|---|---|
Number | 123 | Integer | - | [fieldName] [fieldName]RangeStart [fieldName]RangeEnd |
Number | 123.23 | Float | - | [fieldName] [fieldName]RangeStart [fieldName]RangeEnd |
String | hello | String | - | [fieldName] |
String | em@example.com | String | [fieldName] | |
String | d6b7dde2-0f82-4f85-b906-42704813ff16 | String | UUID | [fieldName] |
String | 2017-05-19T16:59:25Z | String | DateTime | [fieldName] [fieldName]RangeStart [fieldName]RangeEnd |
String | 2017-05-19 | String | Date | [fieldName] [fieldName]RangeStart [fieldName]RangeEnd |
If the number in the sample data is a whole number (no decimal place), the property will be an integer, otherwise it will be a float.
Note: Dragonfruit parses explicit strings with numbers in them (like "123"
) as strings.
In addition to creating a parameter to query the numerical field directly, Dragonfruit will create "range" queries to allow you to set upper and lower bounds on the results returned.
- Type: Integer or Float
-
Query Parameters:
- [property name]: return records in which the field exactly matches the value in the query
- [property name]RangeStart: Return records greater than the value in the query
- [property name]RangeEnd: Return records less than the value in the query
This sample data:
{
"intField": 1,
"floatField": 1.1
}
Would return this Swagger model:
"Sample": {
"properties": {
"floatField": {
"type": "number",
"example": 1.1
},
"intField": {
"type": "integer",
"example": 1
}
}
}
With these queries:
Query Field | Type | Returns |
---|---|---|
intFieldRangeStart | integer | Items which have intFields greater than or equal to the query value |
intFieldRangeEnd | integer | Items which have intFields less than or equal to the the query value |
intField | integer | Items which have intFields equal to the query value |
floatFieldRangeStart | integer | Items which have floatFields greater than or equal to the query value |
floatFieldRangeEnd | integer | Items which have floatFields less than or equal to the the query value |
floatField | integer | Items which have floatFields equal to the query value |
Dragonfruit will translate strings in your sample data into string fields in its model. All string fields are able to be queried directly. Dragonfruit will detect strings which are UUIDs, email addresses, dates and datetime, and add the format, additional validation rules, and in some cases additional queries.
- Type: String
-
Query Parameters:
- [property name]: return records in which the field exactly matches the value in the query
This sample data:
{
"stringField": "hello"
}
Would return this Swagger model:
"Sample": {
"properties": {
"stringField": {
"type": "string",
"example": "hello"
}
}
}
With these queries:
Query Field | Type | Returns |
---|---|---|
stringField | string | Items which have stringFields equal to the query value |
- Type: Email Address
-
Query Parameters:
- [property name]: return records in which the field exactly matches the value in the query
-
Validation Rule: The string must match the regular expression
(?i)[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}
- Format Label: email
This sample data:
{
"emailField": "me@example.com"
}
Would return this Swagger model:
"Sample": {
"properties": {
"emailField": {
"type": "string",
"format": "email",
"example": "me@example.com"
}
}
}
With these queries:
Query Field | Type | Returns |
---|---|---|
emailField | string | Items which have emailFields equal to the query value |
- Type: UUID
-
Query Parameters:
- [property name]: return records in which the field exactly matches the value in the query
-
Validation Rule: The string must match the regular expression
[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
- Format Label: uuid
This sample data:
{
"uuidField": "fc47c0d1-713d-4ee5-8af0-a593a2b35a12"
}
Would return this Swagger model:
"Sample": {
"properties": {
"uuidField": {
"type": "string",
"format": "uuid",
"example": "fc47c0d1-713d-4ee5-8af0-a593a2b35a12"
}
}
}
With these queries:
Query Field | Type | Returns |
---|---|---|
uuidField | string | Items which have uuidFields equal to the query value |
- Type: Date Time
-
Query Parameters:
- [property name]: Return records in which the field exactly matches the value in the query
- [property name]RangeStart: Return records from after the value in the query
- [property name]RangeEnd: Return records from before the value in the query
-
Validation Rule: The string must be parsable as an RFC 3339 date/time string with the format
YYYY
-MM
-DD
THH
:MM
:SS
Z - Format Label: date-time
This sample data:
{
"dateTimeField": "2016-01-01T00:00:00Z"
}
Would return this Swagger model:
"Sample": {
"properties": {
"dateField": {
"type": "string",
"format": "date-time",
"example": "2016-01-01T00:00:00Z"
}
}
}
With these queries:
Query Field | Type | Returns |
---|---|---|
dateTimeFieldRangeStart | integer | Items which have dateTimeFields greater than or equal to the query value |
dateTimeFieldRangeEnd | integer | Items which have dateTimeFields less than or equal to the the query value |
dateTimeField | integer | Items which have dateTimeFields equal to the query value |
- Type: Date
-
Query Parameters:
- [property name]: Return records in which the field exactly matches the value in the query
- [property name]RangeStart: Return records from after the value in the query
- [property name]RangeEnd: Return records from before the value in the query
-
Validation Rule: The string must be parsable as a date string with the format
YYYY
-MM
-DD
- Format Label: date
This sample data:
{
"dateField": "2016-01-01"
}
Would return this Swagger model:
"Sample": {
"properties": {
"dateField": {
"type": "string",
"format": "date",
"example": "2016-01-01"
}
}
}
With these queries:
Query Field | Type | Returns |
---|---|---|
dateFieldRangeStart | integer | Items which have dateFields greater than or equal to the query value |
dateFieldRangeEnd | integer | Items which have dateFields less than or equal to the the query value |
dateField | integer | Items which have dateFields equal to the query value |
Generally, you should use real data when you create a new set of APIs with Dragonfruit. This allows Dragonfruit to introspect the types more cleanly and for non-technical people to help validate that the data is correct. You can, however, add two types of "hints" to data to add important constraints to it. These hints allow you to set bounds on numerical data and to set constrained, enumerated values for strings and numbers.
Bounded ranges allow you to set a minimum and maximum for numerical values. Dragonfruit will reject queries which fall outside the bounds. To add a bound to a data point, add a <>
to the data point in your sample data:
{
"boundedField": "20<>30"
}
In this example, the boundedField
would only allow inputs ranging from 20 to 30. (The <>
symbol tells Dragonfruit to interpret the elements as numbers, even though the data point is a string.)
Enumerated fields are restricted to a set of specific values. To create an enumerated field, separate the elements with a pipe |
:
{
"enumeratedField": "A|B|C|D"
}
In this example, the enumeratedField
would only allow A, B, C and D as inputs.
Because Dragonfruit saves and returns data as JSON, items can have arrays nested within them. Depending on the contents of the array, Dragonfruit will parse and serve it in slightly different ways.
You can include arrays of simple data types (strings and numbers) in your sample data. Arrays can only be acted on in whole - arrays can be added to, replaced in or removed from items, but individual elements of arrays cannot be changed.
You can query elements within an array. For example an item with an array element like this:
{
"arrayField": [
"A",
"B",
"C"
]
}
would be returned by this query: http://your.api/api/resource/?arrayField=A
If your sample data contains an array which contains one or more objects, Dragonfruit will create a child endpoint to access the items within the array (see Endpoints and Operations).
For example, the sample data:
{
"id": 1,
"child": [
{
"branchId": 1
}
]
}
Would be queryable at this endpoint: http://your.api/api/resource/1/branches
Child items are parsed just like parent items - simple data points will follow the same rules as simple data points above and arrays of objects will make sub-endpoints (sub-endpoints can go indefinitely).