Baasic Dynamic Resources enable you to create and manipulate data resources by consuming a RESTful API. This means that your resources are platform/technology agnostic and available through HTTP requests without writing any custom backend code.

This post demonstrates some of the Dynamic Resource features through real-world examples on a simple archetypal TODO list application. The application domain is not very interesting nor complicated, but works well for demonstration purposes. Majority of users are acquainted with the TODO list logic and can focus on understanding Baasic features without worrying about application domain details.

Before you get started

To follow and try the examples in this post you need to create your own Baasic application, know how to Authorize API calls with Baasic and a means of doing HTTP requests - the examples use curl, but using your own preferred method (e.g. Postman) should work just as well. When the application is created, you will get an API key which should be used instead of the <api-key> placeholder in the example API requests. Since Baasic is currently in open beta, all examples use “beta” instead of the <version> placeholder.

Defining A Dynamic Resource

A new dynamic resource is defined by specifying a Dynamic Resource Schema (a regular JSON schema - draft v3), either by writing it yourself, or by using the Baasic Schema API to infer the schema from an example resource JSON object. Once the resource is defined, Baasic creates a dedicated RESTful endpoint for it which supports CRUD operations, paging, sorting, filtering and validation of resource objects.

Examples in the remainder of the post demonstrate how to define 2 resources for the example TODO application: * List - used to hold the notes * Note - a single entry in the list

A usual TODO list application would also have some kind of a user resource for users/accounts, but currently there’s no need to add further complexity by introducing such details, especially since Baasic has a Membership Module which is intended specifically for this purpose. Hence, the examples do not use membership at all, instead they represent that a list belongs to a user by specifying a value for the userId list property.

Resource objects and/or schemas need to be defined in JSON and then used to create Dynamic Resources in Baasic, so let’s do that first.

List Resource

The list can contain multiple notes, has a title and belongs to a single user.

Example of a list resource JSON object:

{
    "id": "LTpInP3M00Kdo6WyHeo1hw",
    "title": "Weekly grocery shopping",
    "userId": "D8xPO4C5rE6B66LZ8wqNBQ"
}

And the corresponding schema for the List resource:

{
    "title": "List",
    "type": "object",
    "properties": {
        "id": {
            "readonly": "true",
            "type": "string"
        },
        "title": {
            "type": "string"
        },
        "userId": {
            "type": "string"
        }
    }
}

As previously mentioned, if you don’t want to write the schema yourself, you can use the Baasic schema API to infer a schema from an example resource JSON object:

curl -H "Content-Type: application/json" -d "{ 'id': 'LTpInP3M00Kdo6WyHeo1hw', 'title': 'Weekly grocery shopping', 'userId': 'D8xPO4C5rE6B66LZ8wqNBQ' }" -X POST http://api.baasic.com/<version>/<api-key>/schemas/generate 

Baasic returns the response with the generated schema:

{
    "properties": {
        "id": {
            "hidden": true,
            "readonly": true,
            "title": "Unique Identifier",
            "type": "string"
        },
        "title": {"type": "string"},
        "userId": {"type": "string"}
    },
    "type": "object"
}

There is one convention that Baasic adheres to when creating Dynamic Resource Schemas - it always defines a hidden read-only property “id” in the schema, regardless if you specify it or not. Baasic automatically generates a unique id for each dynamic resource object so you don’t have to worry about it, but if you want to have an identifying field of a different type (e.g. integer) you have to make sure that the values are unique and name your field differently.

Either your own or the generated schema can be used to define the List Dynamic Resource by creating the List Dynamic Resource Schema in Baasic. The example below uses the generated schema:

curl -H "Content-Type: application/json" -X POST -d "{ 'name': 'List', 'description': 'A TODO list, collection of notes.', 'enforceSchemaValidation': true, 'schema': {'type':'object', 'properties':{'id':{'title':'Unique Identifier','readonly':true,'hidden':true,'type':'string'},'title':{'type':'string'},'userId':{'type':'string' } } } }" http://api.baasic.com/<version>/<api-key>/schemas/

A response is returned containing information about the created Dynamic Resource Schema:

{
    "dateCreated": "2015-06-22T03:40:27.970894Z",
    "dateUpdated": "2015-06-22T03:40:27.970894Z",
    "description": "A TODO list, collection of notes.",
    "enforceSchemaValidation": true,
    "id": "1EO7og6N5qAyDj9VW3FpT3",
    "name": "List",
    "owner": null,
    "ownerId": "mL1l5dz7sgLKJr9T0DP617",
    "schema": {
        "properties": {
            "id": {
                "hidden": true,
                "readonly": true,
                "title": "Unique Identifier",
                "type": "string"
            },
            "title": {"type": "string"},
            "userId": {"type": "string"}
        },
        "type": "object"
    }
}

The enforceSchemaValidation property determines if Baasic should validate creation and updates of resource objects and reject them if they don’t adhere to the Dynamic Resource Schema.

Note Resource

A single entry in the list that contains information about the list which it’s attached to and the text of the entry.

Example of a note resource JSON object:

{
    "id": "zUre3yin8k289oukEQ2SRg",
    "noteText": "Buy muffins for today\'s dessert.",
    "listId": "LTpInP3M00Kdo6WyHeo1hw",
    "ordinal": 0,
    "checked": false
}

And the corresponding schema for the note resource:

{
    "title": "Note Schema",
    "type": "object",
    "properties": {
        "id": {
            "readonly": "true",
            "type": "string"
        },
        "noteText": {
            "type": "string"
        },
        "listId": {
            "type": "string"
        },
        "ordinal": {
            "type": "integer"
        },
        "checked": {
            "type: "boolean"
        }
    }
}

Generating the schema based on the example Note resource object is performed in the same manner as for the List resource example object:

curl -H "Content-Type: application/json" -d "{ 'id': 'zUre3yin8k289oukEQ2SRg', 'noteText': 'Buy muffins for today\'s dessert.', 'listId': 'LTpInP3M00Kdo6WyHeo1hw', 'ordinal': 0, 'checked': false }" -X POST http://api.baasic.com/<version>/<api-key>/schemas/generate 

The generated schema in the response:

{
    "properties": {
        "id": {
            "hidden": true,
            "readonly": true,
            "title": "Unique Identifier",
            "type": "string"
        },
        "listId": {"type": "string"},
        "noteText": {"type": "string"},
        "ordinal": {"type": "integer"},
        "checked": {"type": "boolean"}
    },
    "type": "object"
}

Define the Dynamic Resource for the Note resource by creating the Note Dynamic Resource Schema in Baasic. Our example uses the generated schema:

curl -H "Content-Type: application/json" -X POST -d "{ 'name': 'Note', 'description': 'A TODO note.', 'enforceSchemaValidation': true, 'schema': { 'type': 'object', 'properties': { 'id': { 'hidden': true, 'readonly': true, 'title': 'Unique Identifier', 'type': 'string' }, 'listId': {'type': 'string'}, 'noteText': {'type': 'string'}, 'ordinal': {'type': 'integer'}, 'checked': {'type': 'boolean'} } } }" http://api.baasic.com/<version>/<api-key>/schemas/

The returned response shows information about the created Note Dynamic Resource:

{
    "dateCreated": "2015-06-23T16:50:49.137309Z",
    "dateUpdated": "2015-06-23T16:50:49.137309Z",
    "description": "A TODO note.",
    "enforceSchemaValidation": true,
    "id": "4GZx4c2bqqUL2AJ00LaPE3",
    "name": "Note",
    "owner": null,
    "ownerId": "mL1l5dz7sgLKJr9T0DP617",
    "schema": {
        "properties": {
            "checked": {"type": "boolean"},
            "id": {
                "hidden": true,
                "readonly": true,
                "title": "Unique Identifier",
                "type": "string"
            },
            "listId": {"type": "string"},
            "noteText": {"type": "string"},
            "ordinal": {"type": "integer"}
        },
        "type": "object"
    }
}

Working with Dynamic Resources

With the Dynamic Resources defined, resource objects can be created in Baasic by making POST requests, with resource JSON in the body, to the following Dynamic Resource API endpoint:

http://api.baasic.com/<version>/<api-key>/resources/<resource-name>/

For example, creating two TODO lists (weekly grocery shopping and exercise) with some notes can be done with the following API requests:

Weekly grocery shopping list

curl -H "Content-Type: application/json" -X POST -d "{ 'title': 'Weekly grocery shopping', 'userId': 'D8xPO4C5rE6B66LZ8wqNBQ' }" http://api.baasic.com/<version>/<api-key>/resources/List/

Notice that the unique id wasn’t specified in the request, Baasic generated one automatically and returned it in the response:

{
    "id": "rFeCMP3s7a2y6T9VW3yGYE",
    "title": "Weekly grocery shopping",
    "userId": "D8xPO4C5rE6B66LZ8wqNBQ"
}   

The generated grocery shopping list id from the response can now be used to add some notes to it:

curl -H "Content-Type: application/json" -X POST -d "{ 'noteText': 'Buy muffins for today\'s dessert.', 'listId': 'rFeCMP3s7a2y6T9VW3yGYE', 'ordinal': 0, 'checked': false }" http://api.baasic.com/<version>/<api-key>/resources/Note/

Baasic returns a response with the information about the created note:

{
    "checked": false,
    "id": "6tKs4R0z8AFGf59W0AtZD0",
    "listId": "rFeCMP3s7a2y6T9VW3yGYE",
    "noteText": "Buy muffins for today's dessert."
}

Create the other two remaining notes:

curl -H "Content-Type: application/json" -X POST -d "{ 'noteText': 'Get radishes, carrots and onions for the salad', 'listId': 'rFeCMP3s7a2y6T9VW3yGYE', 'ordinal': 1, 'checked': false }" http://api.baasic.com/<version>/<api-key>/resources/Note/

curl -H "Content-Type: application/json" -X POST -d "{ 'noteText': 'Buy ginger and lemons for ginger iced tea.', 'listId': 'rFeCMP3s7a2y6T9VW3yGYE', 'ordinal': 2, 'checked': false }" http://api.baasic.com/<version>/<api-key>/resources/Note/

Weekly Exercise List

Create a list for weekly exercise:

curl -H "Content-Type: application/json" -X POST -d "{ 'title': 'Weekly exercise', 'userId': 'D8xPO4C5rE6B66LZ8wqNBQ' }" http://api.baasic.com/<version>/<api-key>/resources/List/

The created exercise list id can be found in the response:

{
    "id": "0kRcNikTO4sTTwJ00LrHa0",
    "title": "Weekly exercise",
    "userId": "D8xPO4C5rE6B66LZ8wqNBQ"
}

Add notes to the list:

curl -H "Content-Type: application/json" -X POST -d "{ 'noteText': 'Monday cardio - jogging', 'listId': '0kRcNikTO4sTTwJ00LrHa0', 'ordinal': 0, 'checked': false }" http://api.baasic.com/<version>/<api-key>/resources/Note/

curl -H "Content-Type: application/json" -X POST -d "{ 'noteText': 'Tuesday - HIIT', 'listId': '0kRcNikTO4sTTwJ00LrHa0', 'ordinal': 1, 'checked': false }" http://api.baasic.com/<version>/<api-key>/resources/Note/

curl -H "Content-Type: application/json" -X POST -d "{ 'noteText': 'Wednesday - rest day!', 'listId': '0kRcNikTO4sTTwJ00LrHa0', 'ordinal': 2, 'checked': false }" http://api.baasic.com/<version>/<api-key>/resources/Note/

curl -H "Content-Type: application/json" -X POST -d "{ 'noteText': 'Thursday cardio - bike', 'listId': '0kRcNikTO4sTTwJ00LrHa0', 'ordinal': 3, 'checked': false }" http://api.baasic.com/<version>/<api-key>/resources/Note/

curl -H "Content-Type: application/json" -X POST -d "{ 'noteText': 'Friday - HIIT with kettlebells', 'listId': '0kRcNikTO4sTTwJ00LrHa0', 'ordinal': 4, 'checked': false }" http://api.baasic.com/<version>/<api-key>/resources/Note/

Dynamic Resource querying

Once the resources have been defined and resource objects added, they can be manipulated and queried. While doing these API requests it’s often useful to utilize HAL which is supported by default in Baasic. To get HAL-compatible links on resource objects your requests need to specify the Accept header as application/hal+json, but if you don’t care about HAL just use application/json instead.

Getting all TODO lists

To get the available List resources issue the following request:

curl -H "Accept: application/hal+json" http://api.baasic.com/<version>/<api-key>/resources/List/

The response contains an array of List resource JSON objects in the “item” array, along with HAL links in the “_links” objects:

{
    "_embedded": {
        "item": [
        {
            "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    }
                },
                "id": "rFeCMP3s7a2y6T9VW3yGYE",
                "title": "Weekly grocery shopping",
                "userId": "D8xPO4C5rE6B66LZ8wqNBQ"
        },
        {
            "_embedded": {},
            "_links": {
                "delete": {
                    "href": "http://api.baasic.com/<version>/<api-key>/resources/List/0kRcNikTO4sTTwJ00LrHa0",
                    "templated": false
                },
                "patch": {
                    "href": "http://api.baasic.com/<version>/<api-key>/resources/List/0kRcNikTO4sTTwJ00LrHa0",
                    "templated": false
                },
                "post": {
                    "href": "http://api.baasic.com/<version>/<api-key>/resources/List",
                    "templated": false
                },
                "put": {
                    "href": "http://api.baasic.com/<version>/<api-key>/resources/List/0kRcNikTO4sTTwJ00LrHa0",
                    "templated": false
                },
                "self": {
                    "href": "http://api.baasic.com/<version>/<api-key>/resources/List/0kRcNikTO4sTTwJ00LrHa0",
                    "templated": false
                }
            },
            "id": "0kRcNikTO4sTTwJ00LrHa0",
            "title": "Weekly exercise",
            "userId": "D8xPO4C5rE6B66LZ8wqNBQ"
        }
        ]
    },
        "_links": {
            "find": {
                "href": "http://api.baasic.com/<version>/<api-key>/resources/List{?searchQuery,page,rpp,sort,embed}",
                "templated": true
            },
            "next": {
                "href": "http://api.baasic.com/<version>/<api-key>/resources/List?page=2&rpp=10",
                "templated": false
            },
            "self": {
                "href": "http://api.baasic.com/<version>/<api-key>/resources/List?page=1&rpp=10",
                "templated": false
            }
        },
        "embed": null,
        "page": 1,
        "recordsPerPage": 10,
        "searchQuery": null,
        "sort": null,
        "totalRecords": 2
}

Getting a list of notes for a specific TODO list

Ids of available lists can be obtained from the previous query and then used to filter the notes from a specific list:

curl -G -X GET -H "Accept: application/hal+json" --data-urlencode "searchQuery=WHERE listId = '0kRcNikTO4sTTwJ00LrHa0'" http://api.baasic.com/<version>/<api-key>/resources/Note 

Response returns notes in the list with id 0kRcNikTO4sTTwJ00LrHa0:

{
    "_embedded": {
        "item": [
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/XBVoCIf2laIWTQJ00MBIX1",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/XBVoCIf2laIWTQJ00MBIX1",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/XBVoCIf2laIWTQJ00MBIX1",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/XBVoCIf2laIWTQJ00MBIX1",
                        "templated": false
                    }
                },
                "checked": false,
                "id": "XBVoCIf2laIWTQJ00MBIX1",
                "listId": "0kRcNikTO4sTTwJ00LrHa0",
                "noteText": "Monday cardio - jogging",
                "ordinal": 0
            },
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/C89ofWlhjaQV1AJ00MBwz4",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/C89ofWlhjaQV1AJ00MBwz4",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/C89ofWlhjaQV1AJ00MBwz4",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/C89ofWlhjaQV1AJ00MBwz4",
                        "templated": false
                    }
                },
                "checked": false,
                "id": "C89ofWlhjaQV1AJ00MBwz4",
                "listId": "0kRcNikTO4sTTwJ00LrHa0",
                "noteText": "Tuesday - HIIT",
                "ordinal": 1
            },
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/apsC4Ig6Ma27DQJ00MC573",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/apsC4Ig6Ma27DQJ00MC573",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/apsC4Ig6Ma27DQJ00MC573",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/apsC4Ig6Ma27DQJ00MC573",
                        "templated": false
                    }
                },
                "checked": false,
                "id": "apsC4Ig6Ma27DQJ00MC573",
                "listId": "0kRcNikTO4sTTwJ00LrHa0",
                "noteText": "Wednesday - rest day!",
                "ordinal": 2
            },
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/y53irNMXroHAvL9W0B6BZ2",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/y53irNMXroHAvL9W0B6BZ2",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/y53irNMXroHAvL9W0B6BZ2",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/y53irNMXroHAvL9W0B6BZ2",
                        "templated": false
                    }
                },
                "checked": false,
                "id": "y53irNMXroHAvL9W0B6BZ2",
                "listId": "0kRcNikTO4sTTwJ00LrHa0",
                "noteText": "Thursday cardio - bike",
                "ordinal": 3
            },
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/IOqlS5VgwK25KwJ00MCnS3",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/IOqlS5VgwK25KwJ00MCnS3",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/IOqlS5VgwK25KwJ00MCnS3",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/IOqlS5VgwK25KwJ00MCnS3",
                        "templated": false
                    }
                },
                "checked": false,
                "id": "IOqlS5VgwK25KwJ00MCnS3",
                "listId": "0kRcNikTO4sTTwJ00LrHa0",
                "noteText": "Friday - HIIT with kettlebells",
                "ordinal": 4
            }
        ]
    },
    "_links": {
        "find": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/Note{?searchQuery,page,rpp,sort,embed}",
            "templated": true
        },
        "next": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/Note?searchQuery=WHERE listId='0kRcNikTO4sTTwJ00LrHa0'&page=2&rpp=10",
            "templated": false
        },
        "self": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/Note?searchQuery=WHERE listId='0kRcNikTO4sTTwJ00LrHa0'&page=1&rpp=10",
            "templated": false
        }
    },
    "embed": null,
    "page": 1,
    "recordsPerPage": 10,
    "searchQuery": "WHERE listId='0kRcNikTO4sTTwJ00LrHa0'",
    "sort": null,
    "totalRecords": 5
}

The WHERE clause in the request is actually a part of Baasic Query Language (BQL) - we will dedicate a separate post to this important topic, please stay tuned.

Updating and deleting notes

Let’s say we want to mark the Monday note checked and delete the note for Tuesday using the provided HAL links:

Update Monday note:

curl -X PATCH http://api.baasic.com/<version>/<api-key>/resources/Note/XBVoCIf2laIWTQJ00MBIX1 -H "Content-Type:application/json" -d "{ checked: true }"

Remove Wednesday note:

curl -X DELETE http://api.baasic.com/<version>/<api-key>/resources/Note/apsC4Ig6Ma27DQJ00MC573

To verify that both changes have been made, get all notes for the list again:

curl -G -X GET -H "Accept: application/hal+json" --data-urlencode "searchQuery=WHERE listId = '0kRcNikTO4sTTwJ00LrHa0'" http://api.baasic.com/<version>/<api-key>/resources/Note 

The response shows that the Monday note has been checked and Wednesday note removed:

{
    "_embedded": {
        "item": [
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/C89ofWlhjaQV1AJ00MBwz4",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/C89ofWlhjaQV1AJ00MBwz4",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/C89ofWlhjaQV1AJ00MBwz4",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/C89ofWlhjaQV1AJ00MBwz4",
                        "templated": false
                    }
                },
                "checked": false,
                "id": "C89ofWlhjaQV1AJ00MBwz4",
                "listId": "0kRcNikTO4sTTwJ00LrHa0",
                "noteText": "Tuesday - HIIT",
                "ordinal": 1
            },
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/y53irNMXroHAvL9W0B6BZ2",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/y53irNMXroHAvL9W0B6BZ2",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/y53irNMXroHAvL9W0B6BZ2",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/y53irNMXroHAvL9W0B6BZ2",
                        "templated": false
                    }
                },
                "checked": false,
                "id": "y53irNMXroHAvL9W0B6BZ2",
                "listId": "0kRcNikTO4sTTwJ00LrHa0",
                "noteText": "Thursday cardio - bike",
                "ordinal": 3
            },
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/IOqlS5VgwK25KwJ00MCnS3",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/IOqlS5VgwK25KwJ00MCnS3",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/IOqlS5VgwK25KwJ00MCnS3",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/IOqlS5VgwK25KwJ00MCnS3",
                        "templated": false
                    }
                },
                "checked": false,
                "id": "IOqlS5VgwK25KwJ00MCnS3",
                "listId": "0kRcNikTO4sTTwJ00LrHa0",
                "noteText": "Friday - HIIT with kettlebells",
                "ordinal": 4
            },
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/XBVoCIf2laIWTQJ00MBIX1",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/XBVoCIf2laIWTQJ00MBIX1",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/XBVoCIf2laIWTQJ00MBIX1",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/Note/XBVoCIf2laIWTQJ00MBIX1",
                        "templated": false
                    }
                },
                "checked": true,
                "id": "XBVoCIf2laIWTQJ00MBIX1",
                "listId": "0kRcNikTO4sTTwJ00LrHa0",
                "noteText": "Monday cardio - jogging",
                "ordinal": 0
            }
        ]
    },
    "_links": {
        "find": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/Note{?searchQuery,page,rpp,sort,embed}",
            "templated": true
        },
        "next": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/Note?searchQuery=WHERE listId = '0kRcNikTO4sTTwJ00LrHa0'&page=2&rpp=10",
            "templated": false
        },
        "self": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/Note?searchQuery=WHERE listId = '0kRcNikTO4sTTwJ00LrHa0'&page=1&rpp=10",
            "templated": false
        }
    },
    "embed": null,
    "page": 1,
    "recordsPerPage": 10,
    "searchQuery": "WHERE listId = '0kRcNikTO4sTTwJ00LrHa0'",
    "sort": null,
    "totalRecords": 4
}

Deleting a list with its notes

One thing to note regarding Dynamic Resources is that it does not enforce referential integrity rules and constraints - it’s your responsibility to clean up any related resource objects for a resource object that’s being deleted. In this case, the resource object being deleted is the Weekly exercise list and the related resource objects are all note resource objects which have their listId property set to that list’s id.

The HAL delete links for Weekly exercise notes can be obtained from the previous response and used to delete them:

curl -X DELETE http://api.baasic.com/<version>/<api-key>/resources/Note/C89ofWlhjaQV1AJ00MBwz4

curl -X DELETE http://api.baasic.com/<version>/<api-key>/resources/Note/y53irNMXroHAvL9W0B6BZ2

curl -X DELETE http://api.baasic.com/<version>/<api-key>/resources/Note/IOqlS5VgwK25KwJ00MCnS3

curl -X DELETE http://api.baasic.com/<version>/<api-key>/resources/Note/XBVoCIf2laIWTQJ00MBIX1

Check if the notes are deleted:

curl -G -X GET -H "Accept: application/hal+json" --data-urlencode "searchQuery=WHERE listId = '0kRcNikTO4sTTwJ00LrHa0'" http://api.baasic.com/<version>/<api-key>/resources/Note 

Response shows zero notes matching the lists filter:

{
    "_embedded": {"item": []},
    "_links": {
        "find": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/Note{?searchQuery,page,rpp,sort,embed}",
            "templated": true
        },
        "next": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/Note?searchQuery=WHERE listId = '0kRcNikTO4sTTwJ00LrHa0'&page=2&rpp=10",
            "templated": false
        },
        "self": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/Note?searchQuery=WHERE listId = '0kRcNikTO4sTTwJ00LrHa0'&page=1&rpp=10",
            "templated": false
        }
    },
    "embed": null,
    "page": 1,
    "recordsPerPage": 10,
    "searchQuery": "WHERE listId = '0kRcNikTO4sTTwJ00LrHa0'",
    "sort": null,
    "totalRecords": 0
}

To delete the list, first get all lists and then use the desired lists HAL delete link:

curl -H "Accept: application/hal+json" http://api.baasic.com/<version>/<api-key>/resources/List/

Response shows the lists with their HAL links:

 {
    "_embedded": {
        "item": [
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    }
                },
                "id": "rFeCMP3s7a2y6T9VW3yGYE",
                "title": "Weekly grocery shopping",
                "userId": "D8xPO4C5rE6B66LZ8wqNBQ"
            },
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/0kRcNikTO4sTTwJ00LrHa0",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/0kRcNikTO4sTTwJ00LrHa0",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/0kRcNikTO4sTTwJ00LrHa0",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/0kRcNikTO4sTTwJ00LrHa0",
                        "templated": false
                    }
                },
                "id": "0kRcNikTO4sTTwJ00LrHa0",
                "title": "Weekly exercise",
                "userId": "D8xPO4C5rE6B66LZ8wqNBQ"
            }
        ]
    },
    "_links": {
        "find": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/List{?searchQuery,page,rpp,sort,embed}",
            "templated": true
        },
        "next": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/List?page=2&rpp=10",
            "templated": false
        },
        "self": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/List?page=1&rpp=10",
            "templated": false
        }
    },
    "embed": null,
    "page": 1,
    "recordsPerPage": 10,
    "searchQuery": null,
    "sort": null,
    "totalRecords": 2
} 

Use the Weekly exercise list’s HAL delete link:

curl -X DELETE http://api.baasic.com/<version>/<api-key>/resources/List/0kRcNikTO4sTTwJ00LrHa0

Get all the lists again just to make sure that the list was deleted:

curl -H "Accept: application/hal+json" http://api.baasic.com/<version>/<api-key>/resources/List/

The response shows only the Weekly grocery shopping list so the list was successfully deleted:

{
    "_embedded": {
        "item": [
            {
                "_embedded": {},
                "_links": {
                    "delete": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    },
                    "patch": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    },
                    "post": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List",
                        "templated": false
                    },
                    "put": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    },
                    "self": {
                        "href": "http://api.baasic.com/<version>/<api-key>/resources/List/rFeCMP3s7a2y6T9VW3yGYE",
                        "templated": false
                    }
                },
                "id": "rFeCMP3s7a2y6T9VW3yGYE",
                "title": "Weekly grocery shopping",
                "userId": "D8xPO4C5rE6B66LZ8wqNBQ"
            }
        ]
    },
    "_links": {
        "find": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/List{?searchQuery,page,rpp,sort,embed}",
            "templated": true
        },
        "next": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/List?page=2&rpp=10",
            "templated": false
        },
        "self": {
            "href": "http://api.baasic.com/<version>/<api-key>/resources/List?page=1&rpp=10",
            "templated": false
        }
    },
    "embed": null,
    "page": 1,
    "recordsPerPage": 10,
    "searchQuery": null,
    "sort": null,
    "totalRecords": 1
}

Learn more

The above examples have shown some Dynamic Resource concepts and how to utilize it by sending HTTP requests to the API, but if something is unclear or you want to learn more about other features not shown in this post just consult the API Reference under Dynamic Resources Module. Note that the documentation also contains an entry for the ACL feature which enables you to define rules for finely grained access control to each of your resources. It was not used in the examples due to their simplicity, but the documentation should be enough to infer the usage.

The RESTful API approach of working with Dynamic Resources is excellent when learning the details of how they work, but when building a real world application it’s probably a bit tedious since a significant amount of code needs to be written to communicate with Baasic. Because of that we have created SDKs for different platforms to make the communication with Baasic as easy as possible:

Feel free to leave a comment

comments powered by Disqus