Saltar al contenido principal
Versión: v20 R4 BETA

Calling ORDA class functions

Puede llamar a funciones de clase de modelos de datos definidas para el modelo de datos ORDA a través de sus peticiones REST, para poder beneficiarse de la API expuesta de la aplicación 4D objetivo.

Las funciones se llaman simplemente en peticiones POST en la interfaz ORDA apropiada, sin (). Por ejemplo, si ha definido una función getCity() en la dataclass City, podría llamarla utilizando la siguiente petición:

/rest/City/getCity

con los datos en el cuerpo de la petición POST: ["Aguada"]

En el lenguaje 4D, esta llamada equivale a:

$city:=ds.City.getCity("Aguada")

Sólo las funciones con la palabra clave exposed pueden ser llamadas directamente desde las peticiones REST. Ver la sección Funciones expuestas vs. no expuestas.

Llamadas de las funciones

Las funciones deben llamarse siempre utilizando peticiones POST (una petición GET recibirá un error).

Las funciones son llamadas en el objeto correspondiente en el almacén de datos del servidor.

Función de claseSintaxis
datastore class/rest/$catalog/DataStoreClassFunction
dataclass class/rest/{dataClass}/DataClassClassFunction
entitySelection class/rest/{dataClass}/EntitySelectionClassFunction
/rest/{dataClass}/EntitySelectionClassFunction/$entityset/entitySetNumber
/rest/{dataClass}/EntitySelectionClassFunction/$filter
/rest/{dataClass}/EntitySelectionClassFunction/$orderby
entity class/rest/{dataClass}(key)/EntityClassFunction/

/rest/{dataClass}/Function puede utilizarse para llamar a una función de dataclass o de selección de entidades (/rest/{dataClass} devuelve todas las entidades de la DataClass como una selección de entidades).
La función se busca primero en la clase de selección de entidades. Si no se encuentra, se busca en la dataclass. En otras palabras, si una función con el mismo nombre se define tanto en la clase DataClass como en la clase EntitySelection, la función de clase de DataClass nunca se ejecutará.

Todo el código 4D llamado desde las peticiones REST debe ser hilo seguro si el proyecto se ejecuta en modo compilado, porque el Servidor REST siempre utiliza procesos apropiativos en este caso (el valor de la propiedad Utilizar proceso apropiativo es ignorado por el Servidor REST).

Parámetros

Puede enviar los parámetros a las funciones definidas en las clases usuarios ORDA. Del lado del servidor, se recibirán en las funciones de clase en los parámetros normales $1, $2, etc.

Se aplican las siguientes reglas:

  • Los parámetros deben pasarse en el cuerpo de la petición POST
  • Los parámetros deben estar incluidos en una colección (formato JSON)
  • Todos los tipos de datos escalares soportados en las colecciones JSON pueden ser pasados como parámetros.
  • La selección de entidades y la entidad se pueden pasar como parámetros. El objeto JSON debe contener atributos específicos utilizados por el servidor REST para asignar datos a los objetos ORDA correspondientes: DATACLASS, ENTITY, ENTITIES, DATASET.

Ver este ejemplo y este ejemplo.

Parámetro de valor escalar

El(los) parámetros deben estar simplemente incluirse en una colección definida en el cuerpo. For example, with a dataclass function getCities() receiving text parameters: /rest/City/getCities

Parámetros en el cuerpo: ["Aguada","Paris"]

Todos los tipos de datos JSON son soportados en los parámetros, incluidos los punteros JSON. Las fechas se pueden pasar como cadenas en formato de fecha ISO 8601 (por ejemplo, "2020-08-22T22:00:000Z").

Parámetro de entidad

Las entidades pasadas en los parámetros son referenciadas en el servidor a través de su llave (es decir, propiedad __KEY). Si el parámetro llave se omite en una petición, una nueva entidad se carga en memoria del servidor. También puede pasar valores para todos los atributos de la entidad. Estos valores se utilizarán automáticamente para la entidad manejada en el servidor.

Si la petición envía los valores de atributo modificados para una entidad existente en el servidor, la función de modelo de datos ORDA llamada se ejecutará automáticamente en el servidor con los valores modificados. Esta funcionalidad le permite, por ejemplo, verificar el resultado de una operación en una entidad, tras aplicar todas las reglas de negocio, desde la aplicación cliente. A continuación, puede decidir guardar o no la entidad en el servidor.

PropiedadesTipoDescripción
Atributos de la entidadmixtoOpcional - Valores a modificar
__DATACLASSStringObligatorio - Indica la Dataclass de la entidad
__ENTITYBooleanObligatorio - True para indicar al servidor que el parámetro es una entidad
__KEYmixto (mismo tipo que la llave primaria)Opcional - llave primaria de la entidad
  • Si no se proporciona __KEY, se crea una nueva entidad en el servidor con los atributos dados.
  • Si se proporciona KEY, la entidad correspondiente a KEY se carga en el servidor con los atributos dados

Ver los ejemplos de creación o de actualización de las entidades.

Parámetro de entidad asociado

Las mismas propiedades que para un parámetro de entidad. Además, la entidad relacionada debe existir y ser referenciada por __KEY, que contiene su llave primaria.

Ver los ejemplos para creación o actualización de las entidades con las entidades relacionadas.

Parámetro de selección de entidad

La selección de entidades debe haber sido definida previamente utilizando $method=entityset.

Si la petición envía una selección de entidades modificada al servidor, la función del modelo de datos ORDA llamada se ejecutará automáticamente en el servidor con la selección de entidades modificada.

PropiedadesTipoDescripción
Atributos de la entidadmixtoOpcional - Valores a modificar
__DATASETStringObligatorio - entitySetID (UUID) de la selección de entidades
__ENTITIESBooleanObligatorio - True para indicar al servidor que el parámetro es una selección de entidades

Ver ejemplo para recibir una selección de entidades.

Ejemplos de peticiones

Esta base de datos se expone como un almacén de datos remoto en localhost (puerto 8111):

alt-text

Utilizar una función de clase de datastore

La clase de DataStore US_Cities ofrece una API:

// DataStore class

Class extends DataStoreImplementation

exposed Function getName()
$0:="US cities and zip codes manager"

A continuación, puede ejecutar esta petición:

POST 127.0.0.1:8111/rest/$catalog/getName

Result

{
"result": "US cities and zip codes manager"
}

Utilizar una función de clase de dataclass

La clase de Dataclass City ofrece una PI que devuelve una entidad de ciudad a partir del nombre pasado en parámetro:

// City class

Class extends DataClass

exposed Function getCity()
var $0 : cs.CityEntity
var $1,$nameParam : text
$nameParam:=$1
$0:=This.query("name = :1";$nameParam).first()

A continuación, puede ejecutar esta petición:

POST 127.0.0.1:8111/rest/City/getCity

Petición: ["Aguada"]

Result

El resultado es una entidad:

{
"__entityModel": "City",
"__DATACLASS": "City",
"__KEY": "1",
"__TIMESTAMP": "2020-03-09T08:03:19.923Z",
"__STAMP": 1,
"ID": 1,
"name": "Aguada",
"countyFIPS": 72003,
"county": {
"__deferred": {
"uri": "/rest/County(72003)",
"__KEY": "72003"
}
},
"zips": {
"__deferred": {
"uri": "/rest/City(1)/zips?$expand=zips"
}
}
}

Utilizar una función de clase de una entidad

La clase de entidad CityEntity ofrece una API:

// CityEntity class

Class extends Entity

exposed Function getPopulation()
$0:=This.zips.sum("population")

A continuación, puede ejecutar esta petición:

POST 127.0.0.1:8111/rest/City(2)/getPopulation

Result

{
"result": 48814
}

Utilizar una función clase entitySelection

La clase de selección de entidad CityEntity ofrece una API:

// CitySelection class

Class extends EntitySelection

exposed Function getPopulation()
$0:=This.zips.sum("population")

A continuación, puede ejecutar esta petición:

POST 127.0.0.1:8111/rest/City/getPopulation/?$filter="ID<3"

Result

{
"result": 87256
}

Utilizar una función de clase de selección de entidades y un conjunto de entidades

La clase StudentsSelection tine una función getAgeAverage:

// StudentsSelection Class

Class extends EntitySelection

exposed Function getAgeAverage
C_LONGINT($sum;$0)
C_OBJECT($s)

$sum:=0
For each ($s;This)
$sum:=$sum+$s.age()
End for each
$0:=$sum/This.length

Una vez que haya creado un conjunto de entidades, puede ejecutar esta petición:

POST 127.0.0.1:8044/rest/Students/getAgeAverage/$entityset/17E83633FFB54ECDBF947E5C620BB532

Result

{
"result": 34
}

Utilizar una función de clase de selección de entidades y unorderBy

La clase StudentsSelection tiene una función getLastSummary:

// StudentsSelection Class


Class extends EntitySelection

exposed Function getLastSummary
C_TEXT($0)
C_OBJECT($last)

$last:=This.last()
$0:=$last.firstname+" - "+$last.lastname+" is ... "+String($last.age())

A continuación, puede ejecutar esta petición:

POST 127.0.0.1:8044/rest/Students/getLastSummary/$entityset/?$filter="lastname=b@"&$orderby="lastname"

Result

{
"result": "Wilbert - Bull is ... 21"
}

Utilizar una entidad que se creará en el servidor

La clase de Dataclass Students tiene la función pushData() que recibe una entidad que contiene los datos del cliente. El método checkData() efectúa algunos controles. Si son válidos, la entidad se guarda y se devuelve.

// Students Class

Class extends DataClass

exposed Function pushData
var $1, $entity, $status, $0 : Object

$entity:=$1

$status:=checkData($entity) // $status es un objeto con una propiedad booleana "success"

$0:=$status

If ($status.success)
$status:=$entity.save()
If ($status.success)
$0:=$entity
End if
End if

Lance esta petición:

POST http://127.0.0.1:8044/rest/Students/pushData

Cuerpo de la petición:

[{
"__DATACLASS":"Students",
"__ENTITY":true,
"firstname":"Ann",
"lastname":"Brown"
}]

Como ninguna __KEY es dada, una nueva entidad Students está cargada en el servidor con los atributos del cliente. Como la función pushData() ejecuta una acción save(), la nueva entidad es creada.

Result

{
"__entityModel": "Students",
"__DATACLASS": "Students",
"__KEY": "55",
"__TIMESTAMP": "2020-06-16T10:54:41.805Z",
"__STAMP": 1,
"ID": 55,
"firstname": "Ann",
"lastname": "BROWN",
"schoolID": null,
"school": null
}

Utilizar una entidad a actualizar en el servidor

Igual que el anterior pero con el atributo __KEY

Lance esta petición:

POST:http://127.0.0.1:8044/rest/Students/pushData

Cuerpo de la petición:

[{
"__DATACLASS":"Students",
"__ENTITY":true,
"lastname":"Brownie",
"__KEY":55
}]

Como __KEY es dada, la entidad Students está cargada con llave primaria 55 con el valor lastname recibido por el cliente. Como la función ejecuta una acción save(), la nueva entidad es actualizada.

Result

{
"__entityModel": "Students",
"__DATACLASS": "Students",
"__KEY": "55",
"__TIMESTAMP": "2020-06-16T11:10:21.679Z",
"__STAMP": 3,
"ID": 55,
"firstname": "Ann",
"lastname": "BROWNIE",
"schoolID": null,
"school": null
}

Crear una entidad con una entidad relacionada

En este ejemplo, creamos una nueva entidad Students con la entidad Schools con la llave primaria 2.

Lance esta petición:

POST:http://127.0.0.1:8044/rest/Students/pushData

Cuerpo de la petición:

[{
"__DATACLASS":"Students",
"__ENTITY":true,
"firstname":"John",
"lastname":"Smith",
"school":{"__KEY":2}
}]

Result

{
"__entityModel": "Students",
"__DATACLASS": "Students",
"__KEY": "56",
"__TIMESTAMP": "2020-06-16T11:16:47.601Z",
"__STAMP": 1,
"ID": 56,
"firstname": "John",
"lastname": "SMITH",
"schoolID": 2,
"school": {
"__deferred": {
"uri": "/rest/Schools(2)",
"__KEY": "2"
}
}
}

Actualizar una entidad con una entidad relacionada

En este ejemplo, asociamos una escuela existente a una entidad Students. La clase StudentsEntity tiene una API:

// StudentsEntity class

Class extends Entity

exposed Function putToSchool()
var $1, $school , $0, $status : Object

//$1 es una entidad Schools
$school:=$1
//Asocia la entidad relacionada "school" con la entidad actual "Students"
This.school:=$school

$status:=This.save()

$0:=$status

You run this request, called on a Students entity : POST http://127.0.0.1:8044/rest/Students(1)/putToSchool Body of the request:

[{
"__DATACLASS":"Schools",
"__ENTITY":true,
"__KEY":2
}]

Result

{
"result": {
"success": true
}
}

Recibir una selección de entidades como parámetro

En la clase de Dataclass Students, la función setFinalExam() actualiza una selección de entidad recibida ($1). En realidad, actualiza el atributo finalExam con el valor recibido ($2). Devuelve las llaves primarias de las entidades actualizadas.

// Students class

Class extends DataClass

exposed Function setFinalExam()

var $1, $es, $student, $status : Object
var $2, $examResult : Text

var $keys, $0 : Collection

//Entity selection
$es:=$1

$examResult:=$2

$keys:=New collection()

//Bucle en la selección de entidades
For each ($student;$es)
$student.finalExam:=$examResult
$status:=$student.save()
If ($status.success)
$keys.push($student.ID)
End if
End for each

$0:=$keys

Un conjunto de entidades se crea primero con esta petición:

http://127.0.0.1:8044/rest/Students/?$filter="ID<3"&$method=entityset

A continuación, puede ejecutar esta petición:

POST http://127.0.0.1:8044/rest/Students/setFinalExam

Cuerpo de la petición:

[
{
"__ENTITIES":true,
"__DATASET":"9B9C053A111E4A288E9C1E48965FE671"
},
"Passed"
]

Result

Se han actualizado las entidades con llaves primarias 1 y 2.

{
"result": [
1,
2
]
}

Utilizar una selección de entidades actualizada en el cliente

Utilizando la función getAgeAverage() definida anteriormente.

var $remoteDS, $newStudent, $students : Object
var $ageAverage : Integer

$remoteDS:=Open datastore(New object("hostname";"127.0.0.1:8044");"students")

// $newStudent es una entidad "student" a procesar
$newStudent:=...
$students:=$remoteDS.Students.query("school.name = :1";"Math school")
// Hemos añadido una entidad a la selección de entidades $students en el cliente
$students.add($newStudent)

// Llamamos a una función en la clase StudentsSelection que devuelve la edad media de los estudiantes en la selección de entidades
// La función se utiliza en el servidor en la selección de la entidad $students actualizada, que incluye el estudiante añadido por el cliente
$ageAverage:=$students.getAgeAverage()