以前のブログ記事で、 ORDAクラスと、それが提供するコーディングをより円滑にする可能性について学びました。今回のブログでは、RESTサーバでの使用方法について説明します。
実際に見てみましょう
LearningSystemというデータベースがあり、以下のテーブルを含んでいます。

このデータベースはRESTサーバーとして localhost (ポート8044) で公開されており、そのクラスで定義されたすべての関数はRESTリクエストのPOST操作で呼び出すことができます。
データストアクラスで定義された関数の呼び出し
データストアのオブジェクトは、/rest/$catalogという接頭辞を使って取得します。
DataStoreデータストアクラスには、getStatistics() 関数が定義されています。この関数は、学校に関する情報を持つコレクションを返します。
Class extends DataStoreImplementation
Function getStatistics
C_COLLECTION($0;$result)
C_OBJECT($obj;$school)
$result:=New collection()
For each ($school;This.Schools.all())
$obj:=New object()
$obj.name:=$school.name
$obj.city:=$school.city.name
$obj.numberOfStudents:=$school.students.length
$result.push($obj)
End for each
$0:=$result
http://127.0.0.1:8044/rest/$catalog/getStatisticsのURLで呼び出すことができます。
以下は、サーバーからの応答です。
{
"result": [
{
"name": "Old school",
"city": "Solebury",
"numberOfStudents": 3
},
{
"name": "History Institute",
"city": "Solebury",
"numberOfStudents": 3
},
{
"name": "4D University",
"city": "Hummelstown",
"numberOfStudents": 3
}
]
}
データクラスで定義された関数の呼び出し
データクラスオブジェクトは、/rest/dataClassNameというプレフィックスでアクセスします。
registerStudent() 関数が Schoolsデータクラスで定義されています。この関数は、生徒のデータをオブジェクトで受け取り、生徒の英語レベルが学校の要求レベルを満たしているかどうかをチェックします。英語レベルに問題がなければ、この関数は Studentsエンティティを作成し、保存します。
Class extends DataClass
Function registerStudent
C_OBJECT($1;$data;$student;$school;$result;$0)
$data:=$1
$school:=ds.Schools.query("name = :1";$data.schoolName).first()
$result:=New object("success";True)
If ($data.englishLevel < $school.minAcceptedEnglishLevel)
$result.success:=False
$result.statusText:="The english level is not enough"
$0:=$result
End if
If ($result.success)
$student:=ds.Students.new()
$student.fromObject($data)
$student.finalExam:="To take"
$student.school:=$school
$result:=$student.save()
$0:=$student
End if
http://127.0.0.1:8044/rest/Schools/registerStudent の URL からアクセスできます。
パラメーターはコレクションとして、リクエストのボディに渡す必要があります。
[
{
"firstname": "Mary",
"lastname": "Smith",
"englishLevel": 2,
"schoolName": "Math school"
}
]
以下は、サーバーからの応答です。
{
"__entityModel": "Students",
"__DATACLASS": "Students",
"__KEY": "9",
"__TIMESTAMP": "2020-06-03T13:08:13.542Z",
"__STAMP": 1,
"ID": 9,
"firstname": "Mary",
"lastname": "Smith",
"englishLevel": 2,
"schoolID": 4,
"finalExam": "To take",
"school": {
"__deferred": {
"uri": "/rest/Schools(4)",
"__KEY": "4"
}
}
}
エンティティクラスで定義された関数を呼び出す
エンティティオブジェクトは、/rest/dataClassName(key) というプレフィックスでアクセスします。key はエンティティのプライマリキーです。
StudentsEntityエンティティクラスには、studyingInSameCity() 関数が定義されています。これは、現在のStudent と同じ都市で勉強している他のすべての学生を返します。
Class extends Entity
Function studyingInSameCity
C_OBJECT($0;$city)
$city:=This.school.city
$0:=$city.schools.students.minus(This)
この例は、主キーが 7 のエンティティの場合です。このエンティティには、http://127.0.0.1:8044/rest/Students(7)/studyingInSameCity/?$attributes=firstname, lastname というURLでアクセスしています。
このエンティティに studyingInSameCity() 関数を適用し、返された属性をフィルタリングして firstname とlastname だけを取得します (/?$attributes=firstname, lastname)。
以下はサーバーからの応答です。
{
"__DATACLASS": "Students",
"__entityModel": "Students",
"__GlobalStamp": 0,
"__COUNT": 3,
"__FIRST": 0,
"__ENTITIES": [
{
"__KEY": "5",
"__TIMESTAMP": "2020-06-16T13:59:51.095Z",
"__STAMP": 1,
"firstname": "Ricky",
"lastname": "Coyle"
},
{
"__KEY": "6",
"__TIMESTAMP": "2020-06-16T13:59:51.095Z",
"__STAMP": 1,
"firstname": "Alonzo",
"lastname": "Zapata"
}
],
"__SENT": 3
}
エンティティセレクションクラスで定義された関数を呼び出す
エンティティセレクションオブジェクトには、フィルター構文でアクセスすることができます。例えば、/?$filter=”finalExam=’To take'” とすると、finalExam 属性の値が “To take” であるすべての学生を取得することができます。
エンティティセレクションは他の方法でアクセスすることもできますので、必ずドキュメントを確認してください。
StudentsSelectionエンティティセレクションクラスには、setFinalExam() 関数が定義されています。これは、各生徒の finalExam 属性を与えられた値で更新します。
Class extends EntitySelection
Function setFinalExam
C_TEXT($1;$value)
C_OBJECT($student;$status;$0)
$value:=$1
For each ($student;This) Until (Not($status.success))
$student.finalExam:=$value
$status:=$student.save()
End for each
$0:=$status
この例では、http://127.0.0.1:8044/rest/Students/setFinalExam/?$filter=”finalExam=’To take'” というURLでアクセスしています。
以下はリクエストの本文です。
[
"Passed"
]
これがサーバーからの応答です (該当する生徒はすべて適切に更新されています)。
{
"result": {
"success": true
}
}
HDI をダウンロードして、上記をすべて実際に見てみましょう。
注意
キーワードについては、この投稿を必ずチェックしてください。4D v18 R5以降、関数はデフォルトで公開されていません。公開したい関数をマークするのを忘れないでください。
