REST Anbindung

Dokumente für die Entwicklung von und mit JVx.

REST Anbindung

Postby Development@SIB » Thu Dec 15, 2011 11:46 pm

Wir definieren die Business Logik mit Life-Cycle Objekten am Server. Die Zugriffsberechtigung einer Applikation wird durch einen Security Manager geprüft. Der Zugriff auf die Business Logik erfolgt üblicherweise via Master- oder SubConnections vom Client.

Um die Technologie Unabhängigkeit zu vollenden, steht die Komplette Business Logik einer Applikation auch via REST zur Verfügung.

Für die Benützung der REST Services ist die Autentifizierung mit Benutzername und Passwort notwendig. Als Authentifizierungsmechanismus wird BASIC verwendet Die Überprüfung der Daten wird vom Security Manager der Applikation wie gewohnt durchgeführt. Sie müssen für die Integration der REST Services keine Zeile Source Code verändern.

Folgende Möglichkeiten stehen zur Verfügung:



Wie genau funktioniert die REST Anbindung?

Die REST Implementierung in JVx wurde mit Restlet umgesetzt. Um die REST Services zu nutzen, muss der Deployment Deskriptor wie folgt konfiguriert werden:

Code: Select all
  <servlet> 
    <servlet-name>RestletServlet</servlet-name> 
    <servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
   
    <init-param>
      <param-name>org.restlet.application</param-name>
      <param-value>com.sibvisions.rad.server.http.rest.RESTAdapter</param-value>
    </init-param>
  </servlet> 
 
  <servlet-mapping> 
    <servlet-name>RestletServlet</servlet-name> 
    <url-pattern>/services/rest/*</url-pattern> 
  </servlet-mapping>

Mit dieser Konfiguration stehen folgende Services zur Verfügung:


Zugriff auf Storages (Select, Insert, Update, Delete, Meta Daten)


GET-Request (Select)

Alle Daten abfragen:
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/data/STORAGE_NAME

Genau einen Datensatz abfragen:
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/data/STORAGE_NAME/PK

Wenn der PK aus mehreren Spalten zusammengesetzt ist, müssen die Query Parameter verwendet werden:
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/data/STORAGE_NAME?PKCOLUMN=VALUE&PKCOLUMN2=VALUE

Die Query Parameter können auch verwendet werden, um Filterungen mit Spalten, die nicht PK Spalten sind, durchzuführen.

GET-Response

Der Response enthält immer eine Liste von HashMaps im JSON Format. Als Key wird die Spaltenbezeichnung verwendet.

Beispiel:

Code: Select all
[ { "ID" : 0,
    "POST_ID" : 127,
    "POST_PLZ" : "1127",
    "STIEGE" : 8,
    "STRA_ID" : 68,
    "STRA_NAME" : "Strasse (69)",
    "HAUSNUMMER" : 37,
    "TUERNUMMER" : 79
  },
  { "ID" : 1,
    "POST_ID" : 50,
    "POST_PLZ" : "1050",
    "STIEGE" : 7,
    "STRA_ID" : 55,
    "STRA_NAME" : "Strasse (56)",
    "HAUSNUMMER" : 37,
    "TUERNUMMER" : 60
  },
]


POST-Request (Insert)

Einen neuen Datensatz einfügen:
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/data/STORAGE_NAME

Der Request benötigt eine HashMap im JSON Format. Als Key wird die Spaltenbezeichnung verwendet.

Beispiel:

Code: Select all
{ "POST_ID" : "0",
  "STRA_ID" : "0",
  "HAUSNUMMER" : "9999"
}

POST-Response

Der Response liefert den vollständigen Datensatz im JSON Format:

Code: Select all
{ "ID" : 1008,
  "POST_ID" : 0,
  "POST_PLZ" : "1000",
  "STIEGE" : null,
  "STRA_ID" : 0,
  "STRA_NAME" : "Strasse (1)",
  "HAUSNUMMER" : 9999,
  "TUERNUMMER" : null
}


PUT-Request (Update)

Einen Datensatz per PK aktualisieren:
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/data/STORAGE_NAME/PK

Wenn der PK aus mehreren Spalten zusammengesetzt ist oder der Datensatze nicht über den PK identifiziert werden sollen, müssen die Query Parameter verwendet werden:
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/data/STORAGE_NAME?COLUMN=VALUE&COLUMN2=VALUE

Der Request benötigt eine HashMap im JSON Format. Als Key wird die Spaltenbezeichnung verwendet.

Beispiel:

Code: Select all
{ "ID" : "123",
  "HAUSNUMMER" : "0",
  "STIEGE" : "0",
  "TUERNUMMER" : "0"
}

Es gilt zu beachten, das PK Spalten nicht aktualisiert werden.

PUT-Response

Der Response liefert den vollständigen Datensatz im JSON Format:

Code: Select all
{ "ID" : 0,
  "POST_ID" : 127,
  "POST_PLZ" : "1127",
  "STIEGE" : "0",
  "STRA_ID" : 68,
  "STRA_NAME" : "Strasse (69)",
  "HAUSNUMMER" : "0",
  "TUERNUMMER" : "0"
}


DELETE-Request (Delete)

Genau einen Datensatz löschen:
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/data/STORAGE_NAME/PK

Wenn der PK aus mehreren Spalten zusammengesetzt ist, müssen die Query Parameter verwendet werden:
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/data/STORAGE_NAME?PKCOLUMN=VALUE&PKCOLUMN2=VALUE

DELETE-Response

Der Response liefert die Anzahl der gelöschten Datensätze im JSON Format (als Nummer):

Code: Select all
42


OPTIONS-Request (Meta Daten)

Meta Daten abfragen:
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/data/STORAGE_NAME

OPTIONS-Response

Der Response liefert die Meta Daten im JSON Format:

Code: Select all
{ "autoIncrementColumnNames" : [ "ID" ],
  "columnMetaData" : [ { "allowedValues" : null,
        "autoIncrement" : true,
        "dataType" : 3,
        "defaultValue" : null,
        "label" : "Id",
        "linkReference" : null,
        "name" : "ID",
        "nullable" : false,
        "precision" : 10,
        "scale" : 0,
        "signed" : true,
        "sqltype" : 4,
        "writable" : true
      },
      { "allowedValues" : null,
        "autoIncrement" : false,
        "dataType" : 3,
        "defaultValue" : null,
        "label" : "Post Id",
        "linkReference" : null,
        "name" : "POST_ID",
        "nullable" : false,
        "precision" : 10,
        "scale" : 0,
        "signed" : true,
        "sqltype" : 4,
        "writable" : true
      },
      { "allowedValues" : null,
        "autoIncrement" : false,
        "dataType" : 12,
        "defaultValue" : null,
        "label" : "Plz",
        "linkReference" : { "columnNames" : [ "POST_ID", "POST_PLZ"],
                            "referencedColumnNames" : [ "ID", "PLZ"],
                            "referencedStorage" : ".subStorages.postleitzahlen"
                          },
        "name" : "POST_PLZ",
        "nullable" : false,
        "precision" : 2147483647,
        "scale" : 0,
        "signed" : false,
        "sqltype" : 12,
        "writable" : false
      },
      { "allowedValues" : null,
        "autoIncrement" : false,
        "dataType" : 3,
        "defaultValue" : null,
        "label" : "Stra Id",
        "linkReference" : null,
        "name" : "STRA_ID",
        "nullable" : false,
        "precision" : 10,
        "scale" : 0,
        "signed" : true,
        "sqltype" : 4,
        "writable" : true
      },
      { "allowedValues" : null,
        "autoIncrement" : false,
        "dataType" : 12,
        "defaultValue" : null,
        "label" : "Name",
        "linkReference" : { "columnNames" : [ "STRA_ID", "STRA_NAME"],
                            "referencedColumnNames" : [ "ID", "NAME"],
                            "referencedStorage" : ".subStorages.strassen"
                          },
        "name" : "STRA_NAME",
        "nullable" : false,
        "precision" : 2147483647,
        "scale" : 0,
        "signed" : false,
        "sqltype" : 12,
        "writable" : false
      },
      { "allowedValues" : null,
        "autoIncrement" : false,
        "dataType" : 3,
        "defaultValue" : null,
        "label" : "Hausnummer",
        "linkReference" : null,
        "name" : "HAUSNUMMER",
        "nullable" : false,
        "precision" : 10,
        "scale" : 0,
        "signed" : true,
        "sqltype" : 4,
        "writable" : true
      },
      { "allowedValues" : null,
        "autoIncrement" : false,
        "dataType" : 3,
        "defaultValue" : null,
        "label" : "Stiege",
        "linkReference" : null,
        "name" : "STIEGE",
        "nullable" : true,
        "precision" : 10,
        "scale" : 0,
        "signed" : true,
        "sqltype" : 4,
        "writable" : true
      },
      { "allowedValues" : null,
        "autoIncrement" : false,
        "dataType" : 3,
        "defaultValue" : null,
        "label" : "Tuernummer",
        "linkReference" : null,
        "name" : "TUERNUMMER",
        "nullable" : true,
        "precision" : 10,
        "scale" : 0,
        "signed" : true,
        "sqltype" : 4,
        "writable" : true
      }
    ],
  "columnNames" : [ "ID",
      "POST_ID",
      "POST_PLZ",
      "STRA_ID",
      "STRA_NAME",
      "HAUSNUMMER",
      "STIEGE",
      "TUERNUMMER"
    ],
  "primaryKeyColumnNames" : [ "ID" ],
  "representationColumnNames" : [ "ID",
      "POST_ID",
      "POST_PLZ",
      "STRA_ID",
      "STRA_NAME",
      "HAUSNUMMER",
      "STIEGE",
      "TUERNUMMER"
    ]
}



Aufruf von Actions

Die Server-side Actions können sowohl direkt vom Life-cycle Objekt als auch von verwendeten Business Objekten aufgerufen werden. Die Parameter-Übergabe ist ebenfalls möglich.


GET-Request

Aufruf einer Server-side Action (ohne Parameter):
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/action/ACTION_NAME

Aufruf einer Methode eines Business Objektes (ohne Parameter):
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/object/OBJECT_NAME/ACTION_NAME

GET-Response

Der Response liefert den Rückgabewert der Action im JSON Format.


POST/PUT-Request

Aufruf einer Server-side Action (mit Parameter):
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/action/ACTION_NAME

Aufruf einer Methode eines Business Objektes (mit Parameter):
http://server:port/webapp/services/rest/APPLICATION_NAME/LIFECYCLE_CLASS/object/OBJECT_NAME/ACTION_NAME

Der Request benötigt ein Array von Objekten, befüllt mit den Parametern für die Action.

Beispiel:

Action:

Code: Select all
public String calculate(Number pFirst, Number pSecond)
{
  return "" + pFirst.intValue() + pSecond.intValue();
}

JSON Request:

Code: Select all
[123,1]


POST/PUT-Response

Der Response liefert den Rückgabewert der Action im JSON Format.


Hinweis

Bei Action calls müssen die korrekten Datentypen verwendet werden! Generell sollte auf primitive Datentypen, als Parameter, verzichtet und anstatt von Arrays sollte das List Interface verwendet werden. Weiters empfiehlt sich die Nutzung von Number für alle numerischen Werte. Dadurch werden Probleme aufgrund der JSON Serialisierung vermieden.

Als Life-Cycle Name sollte der Voll qualifiziert Klassenname, mit Package, verwendet werden. Wenn nur der simple Klassen Name verwendet wird, versucht JVx eine passende Klasse zu ermitteln. Sollten mehrere Klassen in Frage kommen, dann wird keine Klasse verwendet. Sie können optional einen Suchpfad in der config.xml der Applikation definieren:

Code: Select all
<application>
  ..
  <rest>
    <search>
      <path>/com/sibvisions/app/myapp</app>
      <path>/com/sibvisions/app/myapp/screens/sub/</app>
    </search>
  </rest>
</application>

Weitere Details finden Sie im Support System.
User avatar
Development@SIB
 
Posts: 311
Joined: Mon Sep 28, 2009 1:54 pm

Re: REST Anbindung

Postby Development@SIB » Mon Apr 24, 2017 2:23 pm

Beispiel für den Zugriff via php:

Syntax: [ Download ] [ Hide ]
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://<server>/DB/services/rest/League/Standings/data/All');
           
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "user:password");
//curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);

$json = json_decode(curl_exec($ch), true);

curl_close($ch);
User avatar
Development@SIB
 
Posts: 311
Joined: Mon Sep 28, 2009 1:54 pm


Return to Dokumentation