In this article, I would like to introduce the RESTForms project - the universal REST API backend on InterSystems Caché 2016.1+ for modern web applications. The idea of the project is simple - after writing several REST API, it became clear that, as a rule, the REST API consists of two parts:
And, although you have to write your own business logic, RESTForms provides everything you need to work with the stored data out of the box.
This project was developed as a backend for JS web applications, so JS can immediately start working with RESTForms, no conversion of data formats, etc. is required.
What can you do with RESTForms:
The following is a table of available API methods that demonstrates what you can do through RESTForms.
URL | Description |
---|---|
test | Test method |
form / info | Class list |
form / info / all | Meta-information of all classes |
form / info /: class | Meta-information of one class |
form / field /: class | Add property to class |
form / field /: class | Change property |
form / field /: class /: property | Remove property |
form / object /: class /: id | Get object |
form / object /: class /: id /: property | Get object property |
form / object /: class | Create object |
form / object /: class /: id | Update object from dynamic object |
form / object /: class | Update object from class object |
form / object /: class /: id | Delete object |
form / objects /: class /: query | Execute SQL query |
form / objects /: class / custom /: query | Run custom SQL query |
/forms
with class broker Form.REST.Main
{"Status": "OK"}
should be displayed {"Status": "OK"}
, you may be asked for a password). do ##class(Form.Util.Init).populateTestForms()
List of class objects:
And class object:
First, you want to know which classes are available. To obtain this information, call:
http://localhost:57772/forms/form/info
You will get something like this in return:
[ { "name":"Company", "class":"Form.Test.Company" }, { "name":"Person", "class":"Form.Test.Person" }, { "name":"Simple form", "class":"Form.Test.Simple" } ]
At the moment, 3 test classes are delivered with RESTForms. Let's look at the metadata for the Person form (class Form.Test.Person). To get this data, you need to call:
http://localhost:57772/forms/form/info/Form.Test.Person
{ "name":"Person", "class":"Form.Test.Person", "displayProperty":"name", "objpermissions":"CRUD", "fields":[ { "name":"name", "type":"%Library.String", "collection":"", "displayName":"Name", "required":0, "category":"datatype" }, { "name":"dob", "type":"%Library.Date", "collection":"", "displayName":"Date of Birth", "required":0, "category":"datatype" }, { "name":"ts", "type":"%Library.TimeStamp", "collection":"", "displayName":"Timestamp", "required":0, "category":"datatype" }, { "name":"num", "type":"%Library.Numeric", "collection":"", "displayName":"Number", "required":0, "category":"datatype" }, { "name":"ge", "type":"%Library.Integer", "collection":"", "displayName":"Age", "required":0, "category":"datatype" }, { "name":"relative", "type":"Form.Test.Person", "collection":"", "displayName":"Relative", "required":0, "category":"form" }, { "name":"Home", "type":"Form.Test.Address", "collection":"", "displayName":"House", "required":0, "category":"serial" }, { "name":"company", "type":"Form.Test.Company", "collection":"", "displayName":"Company", "required":0, "category":"form" } ] }
What does all of this mean?
Class Metadata:
Metadata properties:
/// Test form: Person Class Form.Test.Person Extends (%Persistent, Form.Adaptor) { /// Parameter FORMNAME = "Person"; /// /// (C), (R), (U), (D) Parameter OBJPERMISSIONS As %String = "CRUD"; /// "" Parameter DISPLAYPROPERTY As %String = "name"; /// - Parameter FORMORDERBY As %String = "dob"; /// Property name As %String(DISPLAYNAME = "Name"); /// Property dob As %Date(DISPLAYNAME = "Date of Birth"); /// Property num As %Numeric(DISPLAYNAME = "Number") [ InitialExpression = "2.15" ]; /// , Property ge As %Integer(DISPLAYNAME = "Age") [ Calculated, SqlComputeCode = { set {*}=##class(Form.Test.Person).currentAge({dob})}, SqlComputed, SqlComputeOnChange = dob ]; /// ClassMethod currentAge(date As %Date = "") As %Integer [ CodeMode = expression ] { $Select(date="":"",1:($ZD($H,8)-$ZD(date,8)\10000)) } /// - Form.Test.Person Property relative As Form.Test.Person(DISPLAYNAME = "Relative"); /// Property Home As Form.Test.Address(DISPLAYNAME = "House"); /// , /// http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GOBJ_relationships Relationship company As Form.Test.Company(DISPLAYNAME = "Company") [ Cardinality = one, Inverse = employees ]; }
To make a stored class accessible to RESTForms, you need to:
FORMNAME
with value - class nameOBJPERMISSIONS
parameter - what can be done with class objects (CRUD)DISPLAYPROPERTY
- the name of the property used to display the name of the objectFORMORDERBY
parameter — the default property for sorting by query using RESTFormsAfter we have generated some test data (see Installation, step 4), let's get Person with ID 1. To get an object, call:
http://localhost:57772/forms/form/object/Form.Test.Person/1
And get the answer:
{ "_class":"Form.Test.Person", "_id":1, "name":"Klingman,Rhonda H.", "dob":"1996-10-18", "ts":"2016-09-20T10:51:31.375Z", "num":2.15, "ge":20, "relative":null, "Home":{ "_class":"Form.Test.Address", "House":430, "Street":"5337 Second Place", "City":"Jackson" }, "company":{ "_class":"Form.Test.Company", "_id":60, "name":"XenaSys.com", "employees":[ null ] } }
To change an object (in particular, the num property), call:
PUT http://localhost:57772/forms/form/object/Form.Test.Person
With body:
{ "_class":"Form.Test.Person", "_id":1, "num":3.15 }
Note that to improve speed, only _class
, _id
and changed properties should be in the body of the request.
Now, let's create a new object. Call:
POST http://localhost:57772/forms/form/object/Form.Test.Person
With body:
{ "_class":"Form.Test.Person", "name":"Test person", "dob":"2000-01-18", "ts":"2016-09-20T10:51:31.375Z", "num":2.15, "company":{ "_class":"Form.Test.Company", "_id":1 } }
If the creation of the object is completed successfully, RESTForms will return an identifier:
{"Id": "101"}
Otherwise, a JSON error will be returned. Note that persistent properties must be referenced through the _class
and _id
.
You can try RESTForms online here (user: Demo, password: Demo). In addition, there is an application RESTFormsUI - editor for RESTForms data. A demo stand is available here (user: Demo, password: Demo). Screenshot of the list of classes:
RESTForms does almost all of the work required of the REST API for stored classes.
In this article, I just started talking about the functionality of RESTForms. In the following, I would like to talk about some additional functions, namely, queries that allow the client to safely receive data sets without the risk of SQL injection.
Source: https://habr.com/ru/post/330822/
All Articles