[deepamehta-devel] Updating composite topics via REST API

Jörg Richter jri at deepamehta.de
Mon Oct 3 23:56:34 CEST 2016


Hi Robert,

to update a Person topic:

curl -H Cookie:JSESSIONID=nv23xiaj5n751et10ga74d1u -H Cookie:dm4_workspace_id=2954 -H Content-Type:application/json -X PUT localhost:8080/core/topic/4703 -d '{
    "childs": {
        "dm4.contacts.person_name": {
            "dm4.contacts.last_name": "Schmidt-Schacht"
        },
        "dm4.contacts.phone_number#dm4.contacts.phone_entry": [
            {
                "value": "0177 123 45 000",
                "assoc": {
                    "childs": {
                        "dm4.contacts.phone_label": "ref_id:1912"
                    }
                }
            }
        ]
    }
}'


To update a topic PUT the new topic data to the "/core/topic/<id>" resource. Here <id> stands for the ID of the topic to update. Pass the new topic data in the request body as a JSON object.

It is sufficient to pass only the topic data you want to change. The example changes the person's last name and adds a mobile number. Note that the person's first name is not contained in the update request and thus it will not change. You could say that the topic data in the update request is kind of "merged" with the current person data as stored in the DB.



Lets investigate the Person model: you see that "Person" has "Phone" as a child type. Phone is a "simple" (in contrast to "composite") type and uses "Text" as its data type. Phone is defined with cardinality "Many", that is a Person can have many phone numbers. Furthermore Phone makes use of a Custom Association Type, which is "Phone Entry". That is at instance-level a Person topic will connect Phone topics via associations of type "Phone Entry". The association type "Phone Entry" is a composite type, which have "Phone Label" as a child type. 5 Phone Label instances are pre-defined by the dm4-contacts module: "home", "home fax", "mobile", "work", and "work fax".

To investigate the Person definition click the "Person" topic type, and then "Edit".



As topic type Phone (whose URI is "dm4.contacts.phone_number") is defined as "Many" you must specify an *array* in your update request:

    "dm4.contacts.phone_number#dm4.contacts.phone_entry": [
        ...
    ]

(Remember from my previous posting, the "#dm4.contacts.phone_entry" qualification is required as the Phone definition makes use of a Custom Association Type.)

As "Phone" is a simple type you could just specify simple values in the array:

    [
        "123 456", "234 567", "345 678"
    ]

This would add 3 phone numbers to the person. However these would not be annotated by a Phone Label ("home", "mobile", ...). As a phone label is represented as a child topic of the association (that connects a Phone to a Person), the array elements in your update request must look like this:

    [
        {
            "value": "0177 123 45 000",
            "assoc": {
                "childs": {
                    "dm4.contacts.phone_label": "ref_id:1912"
                }
            }
        },
        {
            "value": "030 876 54 321",
            "assoc": {
                "childs": {
                    "dm4.contacts.phone_label": "ref_id:1909"
                }
            }
        }
    ]

This example adds 2 phone numbers to the person, one mobile number, and one home number. Here 1912 and 1909 are the IDs of the "mobile" and "home" Phone Label topics respectively.

Remember from my previous posting, the "ref_id:" prefix is needed as Phone Label is defined via Aggregation Definition (in contrast to Composition Definition). That is the pre-defined 5 Phone Label topics are supposed to be shared by all Phone Entry associations.

OK, now we've added 2 phone numbers to the person. If you want add another one, just PUT another array with one more element. But how can you specify that you want to *change* a particular element, to *delete* a particular entry?

If you want e.g. change the mobile number "0177 123 45 000" to "0177 123 45 111" you would PUT this array:

    [
        {
            "id": 4877,
            "value": "0177 123 45 111"
        }
    ]

Here, 4877 is the ID of the Phone topic you want to update. And: as the "assoc" property is not specified the Phone Label attached to the existing Phone Entry association will not change.

In order to update a particular child topic which is defined as "Cardinality Many" you must specify its ID. Otherwise DM can't know to which child topic your update data applies to. If no ID is given a new child topic with that data will be created.

Note that this is different for "Cardinality One" child topics. In this case no ID is needed (but will be no problem if contained in the request anyways). The update data applies to the one and only topic which exists already (resp. a new one is created if no one exists already).

OK, now about deleting a particular phone number:

    [
        "del_id:4877"
    ]

Besides "ref_id:" another way to refer to an existing topic is the "del_id:" prefix. The actual semantics of "del_id:" depends on wether the child is defined via "Composition Definition" or "Aggregation Definition". In case of Composition Definition the child topic itself is deleted. In case of Aggregation Definition however only the so-called "assignment" is deleted (that is the association that connects the child topic to the parent topic). The child topic itself is NOT deleted as it might still be shared with other parent topics.

In the example, 4877 is the ID of the Phone topic you want to delete. Note that Phone is defined via Composition Definition (as a Phone number is not shared by several Persons).

OK, how can your frontend know all the IDs of the person's child topics in order to build the one big Person update request?

In general you can ask the Core Service for a particular (single or composite) topic by using one of these 3 GET requests (assume 4703 to be the ID of a Person topic):

    GET /core/topic/4703
    GET /core/topic/4703?include_childs=true
    GET /core/topic/4703?include_childs=true&include_assoc_childs=true

The 1st form just returns that Person topic, without its child topics.
The 2nd form returns the Person topic and *all* its child topics as well. You'll also get details about the associations that connect the childs to their parent topics (in the "assoc" property). However, in case these associations are *composite* as well (in contrast to *simple*) you'll NOT get the child topics of these associations.
These are included in the response if you use the 3rd form of the GET request.

So, to display an update form your frontend will typically send these requests:
- a GET request (2nd form) for the topic being edited
- further GET requests to build the combo boxes (as mentioned in my previous posting), this is one get-all-instances request (GET /core/topic/by_type/<uri>) for every child type which is defined as Aggregation Definition.

This way you'll have all the IDs available at client-side to update a composite topic of arbitrary complexity, including
- creating new child topics
- updating child topics
- deleting child topics
- assign existing child topics
- re-assign child topics
- deleting child topic assignments
- all supported for both, single-valued and multiple-valued childs ("Cardinality")

And all that in a single request, that is in a single database transaction.

Cheers,
Jörg

-------------- n�chster Teil --------------
Ein Dateianhang mit HTML-Daten wurde abgetrennt...
URL: <http://lists.deepamehta.de/pipermail/devel-lists.deepamehta.de/attachments/20161003/b30bbbf4/attachment.html>
-------------- n�chster Teil --------------
Ein Dateianhang mit Bin�rdaten wurde abgetrennt...
Dateiname   : PastedGraphic-3.png
Dateityp    : image/png
Dateigr��e  : 65379 bytes
Beschreibung: nicht verf�gbar
URL         : <http://lists.deepamehta.de/pipermail/devel-lists.deepamehta.de/attachments/20161003/b30bbbf4/attachment.png>
-------------- n�chster Teil --------------
Ein Dateianhang mit Bin�rdaten wurde abgetrennt...
Dateiname   : PastedGraphic-5.png
Dateityp    : image/png
Dateigr��e  : 99228 bytes
Beschreibung: nicht verf�gbar
URL         : <http://lists.deepamehta.de/pipermail/devel-lists.deepamehta.de/attachments/20161003/b30bbbf4/attachment-0001.png>
-------------- n�chster Teil --------------
Ein Dateianhang mit Bin�rdaten wurde abgetrennt...
Dateiname   : signature.asc
Dateityp    : application/pgp-signature
Dateigr��e  : 496 bytes
Beschreibung: Message signed with OpenPGP using GPGMail
URL         : <http://lists.deepamehta.de/pipermail/devel-lists.deepamehta.de/attachments/20161003/b30bbbf4/attachment.sig>


More information about the devel mailing list