Skip to main content
Version: v18

Manipulating Data

All exposed datastore classes, attributes and methods can be accessed through REST. Dataclass, attribute, and method names are case-sensitive; however, the data for queries is not.

Querying data

To query data directly, you can do so using the $filter function. For example, to find a person named "Smith", you could write:

http://127.0.0.1:8081/rest/Person/?$filter="lastName=Smith"

Adding, modifying, and deleting entities

With the REST API, you can perform all the manipulations to data as you can in 4D.

To add and modify entities, you can call $method=update. If you want to delete one or more entities, you can use $method=delete.

Besides retrieving a single entity in a dataclass using {dataClass}({key}), you can also write a method in your DataClass class and call it to return an entity selection (or a collection) by using {dataClass}/{method}.

Before returning the collection, you can also sort it by using $orderby one one or more attributes (even relation attributes).

Add the $skip (to define with which entity to start) and $top/$limit (to define how many entities to return) REST requests to your queries or entity selections to navigate the collection of entities.

Creating and managing entity set

An entity set (aka entity selection) is a collection of entities obtained through a REST request that is stored in 4D Server's cache. Using an entity set prevents you from continually querying your application for the same results. Accessing an entity set is much quicker and can improve the speed of your application.

To create an entity set, call $method=entityset in your REST request. As a measure of security, you can also use $savedfilter and/or $savedorderby when you call $filter and/or $orderby so that if ever the entity set timed out or was removed from the server, it can be quickly retrieved with the same ID as before.

To access the entity set, you must use $entityset/{entitySetID}, for example:

/rest/People/$entityset/0AF4679A5C394746BFEB68D2162A19FF

By default, an entity set is stored for two hours; however, you can change the timeout by passing a new value to $timeout. The timeout is continually being reset to the value defined for its timeout (either the default one or the one you define) each time you use it.

If you want to remove an entity set from 4D Server's cache, you can use $method=release.

If you modify any of the entity's attributes in the entity set, the values will be updated. However, if you modify a value that was a part of the query executed to create the entity set, it will not be removed from the entity set even if it no longer fits the search criteria. Any entities you delete will, of course, no longer be a part of the entity set.

If the entity set no longer exists in 4D Server's cache, it will be recreated with a new default timeout of 10 minutes. The entity set will be refreshed (certain entities might be included while others might be removed) since the last time it was created, if it no longer existed before recreating it.

Using $entityset/{entitySetID}?$logicOperator... &$otherCollection, you can combine two entity sets that you previously created. You can either combine the results in both, return only what is common between the two, or return what is not common between the two.

A new selection of entities is returned; however, you can also create a new entity set by calling $method=entityset at the end of the REST request.

Calculating data

By using $compute, you can compute the average, count, min, max, or sum for a specific attribute in a dataclass. You can also compute all values with the $all keyword.

For example, to get the highest salary:

/rest/Employee/salary/?$compute=sum

To compute all values and return a JSON object:

/rest/Employee/salary/?$compute=$all

Getting data from methods

You can call 4D project methods that are exposed as REST Service. A 4D method can return in $0:

  • an object
  • a collection

The following example is a dataclass method that reveives parameters and returns an object:

// 4D findPerson method
C_TEXT($1;$firstname;$2;$lastname)
$firstname:=$1
$lastname:=$2

$0:=ds.Employee.query("firstname = :1 and lastname = :2";$firstname;$lastname).first().toObject()

The method properties are configured accordingly on the 4D project side:

alt-text

Then you can send the following REST POST request, for example using the HTTP Request 4D command:

C_TEXT($content)
C_OBJECT($response)

$content:="[\"Toni\",\"Dickey\"]"

$statusCode:=HTTP Request(HTTP POST method;"127.0.0.1:8044/rest/Employee/findPerson";$content;$response)

Method calls are detailed in the {dataClass} section.

Selecting Attributes to get

You can always define which attributes to return in the REST response after an initial request by passing their path in the request (e.g., Company(1)/name,revenues/)

You can apply this filter in the following ways:

ObjectSyntaxExample
Dataclass{dataClass}/{att1,att2...}/People/firstName,lastName
Collection of entities{dataClass}/{att1,att2...}/?$filter="{filter}"/People/firstName,lastName/?$filter="lastName='a@'"
Specific entity{dataClass}({ID})/{att1,att2...}/People(1)/firstName,lastName
{dataClass}:{attribute}(value)/{att1,att2...}//People:firstName(Larry)/firstName,lastName/
Entity selection{dataClass}/{att1,att2...}/$entityset/{entitySetID}/People/firstName/$entityset/528BF90F10894915A4290158B4281E61

The attributes must be delimited by a comma, i.e., /Employee/firstName,lastName,salary. Storage or relation attributes can be passed.

Examples

Here are a few examples, showing you how to specify which attributes to return depending on the technique used to retrieve entities.

You can apply this technique to:

  • Dataclasses (all or a collection of entities in a dataclass)
  • Specific entities
  • Entity sets

Dataclass Example

The following requests returns only the first name and last name from the People dataclass (either the entire dataclass or a selection of entities based on the search defined in $filter).

GET /rest/People/firstName,lastName/

Result:

{
__entityModel: "People",
__COUNT: 4,
__SENT: 4,
__FIRST: 0,
__ENTITIES: [
{
__KEY: "1",
__STAMP: 1,
firstName: "John",
lastName: "Smith"
},
{
__KEY: "2",
__STAMP: 2,
firstName: "Susan",
lastName: "O'Leary"
},
{
__KEY: "3",
__STAMP: 2,
firstName: "Pete",
lastName: "Marley"
},
{
__KEY: "4",
__STAMP: 1,
firstName: "Beth",
lastName: "Adams"
}
]
}

GET /rest/People/firstName,lastName/?$filter="lastName='A@'"/

Result:

{
__entityModel: "People",
__COUNT: 1,
__SENT: 1,
__FIRST: 0,
__ENTITIES: [
{
__KEY: "4",
__STAMP: 4,
firstName: "Beth",
lastName: "Adams"
}
]
}

Entity Example

The following request returns only the first name and last name attributes from a specific entity in the People dataclass:

GET /rest/People(3)/firstName,lastName/

Result:

{
__entityModel: "People",
__KEY: "3",
__STAMP: 2,
firstName: "Pete",
lastName: "Marley"
}

GET /rest/People(3)/

Result:

{
__entityModel: "People",
__KEY: "3",
__STAMP: 2,
ID: 3,
firstName: "Pete",
lastName: "Marley",
salary: 30000,
employer: {
__deferred: {
uri: "http://127.0.0.1:8081/rest/Company(3)",
__KEY: "3"
}
},
fullName: "Pete Marley",
employerName: "microsoft"

}

Entity Set Example

Once you have created an entity set, you can filter the information in it by defining which attributes to return:

`GET /rest/People/firstName,employer.name/$entityset/BDCD8AABE13144118A4CF8641D5883F5?$expand=employer

Viewing an image attribute

If you want to view an image attribute in its entirety, write the following:

GET /rest/Employee(1)/photo?$imageformat=best&$version=1&$expand=photo

For more information about the image formats, refer to $imageformat. For more information about the version parameter, refer to $version.

Saving a BLOB attribute to disk

If you want to save a BLOB stored in your dataclass, you can write the following:

GET /rest/Company(11)/blobAtt?$binary=true&$expand=blobAtt

Retrieving only one entity

You can use the {dataClass}:{attribute}(value) syntax when you want to retrieve only one entity. It's especially useful when you want to do a related search that isn't created on the dataclass's primary key. For example, you can write:

GET /rest/Company:companyCode("Acme001")