REST-API und Websocket-Events von ARSnova

Aus THM-Wiki
(Weitergeleitet von RESTful Web-API für ARSnova2)
Wechseln zu: Navigation, Suche

API-Ressourcen

Vorbedingungen

authenticated Es wird vorausgesetzt, dass eine gültige Session-ID als Teil eines Cookies (Parametername: JSESSIONID) im HTTP-Request-Header gesendet wird.
valid keyword Es wird vorausgesetzt, dass eine ARSnova-Session mit dem entsprechenden keyword (die achtstellige generierte Sitzungsnummer) existiert.

Globale Query-Parameter

Die folgenden Parameter sind für alle Ressourcen gültig, die eine Liste von Daten zurückgeben. Bisher besteht allerdings nur eine Implementierung für den Parameter user.

user Benutzer, für den Daten abgerufen werden sollen [Params 1]
sort [NYI] Name des Attributs, nach dem sortiert werden soll
order [NYI] Sortierrichtung (asc, desc)
limit [NYI] maximale Anzahl an zurückgegebenen Datensätzen (in Kombination mit offset)
offset [NYI] Datensätze überspringen (in Kombination mit limit)
  1. Die Abfrage von Daten eines anderen Benutzers ist nur mit administrativen Berechtigungen möglich. Ansonsten muss der übergebende Benutzername mit dem Namen des authentifizierten Benutzers übereinstimmen. Um die Zustandslosigkeit der API zu gewährleisten, muss der Wert auch dann angegeben werden, wenn benutzerspezifische Daten für den aktuellen Benutzer abgefragt werden sollen.

URL-Liste

Die im folgenden aufgelisteten Ressourcen der öffentlichen API werden, sofern nicht anders vermerkt, als stabil betrachtet. In eckigen Klammern angegebene Bestandteile der URL sind optional. Durch geschweifte Klammern umschlossene Bestandteile sind Parameternamen, die durch einen entsprechenden Wert ersetzt werden müssen.

Resource Verb URL Description Request encoding Request query/body structure Response code and encoding [API 1] Response structure (if not text/plain) Preconditions
Session GET /session/ [API 2] Retrieves a list of Sessions. Query string parameters: visitedonly (boolean), ownedonly (boolean) [API 3] 501, text/plain (no true parameter); 200, application/json Session[] authenticated
Session POST /session/ Creates a new Session and returns the Session's data. application/json Session 201, application/json Session authenticated
Session GET /session/{keyword} Retrieves a Session. [API 4] none none 200, application/json Session authenticated, valid keyword
Session POST /session/{keyword}/online [DEPRECATED] Adds the user to the list of online users and returns login details. [API 5] none none 201, application/json LoggedIn authenticated, valid keyword
Session POST /session/{keyword}/lock Locks or unlocks a Session Query string parameters: lock (boolean, optional, default: true) 204, application/json Session authenticated, valid keyword
LecturerQuestion GET /session/{keyword}/lecturerquestion/ Retrieves LecturerQuestions for a Session. Query string unansweredonly (boolean) [NYI] 200, application/json LecturerQuestion[] authenticated, valid keyword
LecturerQuestion POST /session/{keyword}/lecturerquestion/ Creates a new LecturerQuestion for a Session and returns the LecturerQuestion's data. application/json LecturerQuestion 201, application/json LecturerQuestion authenticated, valid keyword
LecturerQuestion PUT [/session/{keyword}]/lecturerquestion/{lecturerQuestionId} Updates an existing LecturerQuestion. application/json LecturerQuestion 204, application/json none authenticated
LecturerQuestion GET [/session/{keyword}]/lecturerquestion/{lecturerQuestionId} Retrieves a LecturerQuestion. none none 200, application/json LecturerQuestion authenticated
LecturerQuestion DELETE [/session/{keyword}]/lecturerquestion/{lecturerQuestionId} Deletes a LecturerQuestion. none none 204, application/json none authenticated
LecturerQuestion POST [/session/{keyword}]/lecturerquestion/{lecturerQuestionId}/publish Publishes a LecturerQuestion to the audience. Query string parameters: publish (boolean, optional, default: true) 204, application/json none authenticated
LecturerQuestion GET /session/{keyword}/lecturerquestion/statistics [NYI] Retrieves statistics for LecturerQuestions of a Session. none none 200, application/json properties: tbd authenticated, valid keyword
LecturerQuestionAnswer GET [/session/{keyword}]/lecturerquestion/{lecturerQuestionId}/answer/ Retrieves Answers for a LecturerQuestion. Query string createdonly (boolean) [NYI] 200, application/json Answer[] or Answer if createdonly authenticated, valid keyword
LecturerQuestionAnswer POST [/session/{keyword}]/lecturerquestion/{lecturerQuestionId}/answer/ Creates an Answer to a LecturerQuestion. application/json Answer 201, application/json Answer authenticated, valid keyword
LecturerQuestionAnswer PUT [/session/{keyword}]/lecturerquestion/{lecturerQuestionId}/answer/{answerId} Updates an Answer to a LecturerQuestion. application/json Answer 200, application/json Answer[API 6] authenticated, valid keyword
LecturerQuestionAnswer DELETE [/session/{keyword}]/lecturerquestion/{lecturerQuestionId}/answer/{answerId} Deletes an Answer. none none 204, application/json none authenticated, valid keyword
InterposedQuestion GET /session/{keyword}/interposed/ Retrieves all InterposedQuestions for a Session. none none 200, application/json InterposedQuestion[][API 7] authenticated, valid keyword
InterposedQuestion POST /session/{keyword}/interposed/ Creates a new InterposedQuestion for a Session and returns the InterposedQuestion's data. application/json AudienceQuestion 201, application/json InterposedQuestion authenticated, valid keyword
InterposedQuestion GET /session/{keyword}/interposed/{interposedQuestionId} Retrieves an InterposedQuestion. none none 200, application/json InterposedQuestion authenticated
InterposedQuestion DELETE /session/{keyword}/interposed/{interposedQuestionId} Deletes an InterposedQuestion. none none 204, application/json none authenticated
InterposedQuestion DELETE /session/{keyword}/interposed/ Deletes all InterposedQuestions. none none 204, application/json none authenticated
Statistics GET /statistics Retrieves global statistics. none none 200, application/json properties: answers, questions, openSessions, closedSessions, activeUsers none
  1. HTTP statuses triggered by failed preconditions are not listed.
  2. Attention: The trailing slash may not be omitted for resources retrieving a collection.
  3. Without administrative privileges either visitedonly or ownedonly has to be set true.
  4. Currently also adds the user to the list of online users but this behaviour could be changed (use Socket.IO instead).
  5. Deprecated in favor of use of Socket.IO.
  6. This is inconsistent with the way **/lecturerquestion/{lecturerQuestionId} handles PUT requests.
  7. The text property is not set (retrieve a particular InterposedQuestion if needed).

Aufbau der JSON-Objekte

Die im folgenden aufgelisteten Datenstrukturen werden für die Abfrage, Erstellung und Änderung von Daten verwendet und im HTTP-Body in JSON-Form gesendet. Bei Abfragen werden eventuell weitere Attribute gesendet, die hier jedoch nicht aufgelistet sind, da sie nur für interne Zwecke gedacht sind. Auf der API aufbauende Applikationen sollten diese Attribute nicht verwenden. Zu diesen Attributen gehören unter anderem _rev, type und sessionId.

Session

Property Data type Read only Remarks
name String no
shortName String[12] no
keyword int[8] yes
creator String yes
active boolean no
lastOwnerActivity Unix timestamp (ms) yes
courseType String yes
courseId String yes
courseSession boolean yes Does the session belong to a course (e.g. Moodle)?

LecturerQuestion

Property Data type Read only Remarks
_id String yes
questionType String no
subject String[?] no
text String no
active boolean no
releasedFor String no
possibleAnswers PossibleAnswer[] no
noCorrect boolean no
sessionKeyword boolean yes
timestamp Unix timestamp (ms) yes
number int ?
duration int ?
showStatistic boolean no
showAnswer boolean no

InterposedQuestion

Property Data type Read only Remarks
_id String yes
subject String[?] no
text String no
sessionId [DEPRECATED] String yes The id should be only be used internally by the backend. The sessionKeyword property should be used instead as soon as it is implemented.
sessionKeyword [NYI] String yes
timestamp Unix timestamp (ms) yes
read boolean ? This property is automatically set true when the particular InterposedQuestion is retrieved.

PossibleAnswer

Property Data type Read only Remarks
id String ?
text String no
correct boolean no

Answer

Property Data type Read only Remarks
_id String yes
questionId String yes
answerText String no
answerSubject String no
user String yes
timestamp Unix timestamp (ms) yes
answerCount int ?

Authentifizierung

Für die Verwendung der meisten API-Ressourcen ist eine Authentifizierung erforderlich. Für diese werden die folgenden URLs bereitgestellt:

/auth/login

Abhängig von den übergebenden Query-Parametern wird eine HTTP-Weiterleitung an einen Login-Dienst durchgeführt.

Query-Parameter

type der zu verwendende Dienst (guest, cas, google, facebook)
user Benutzername (nur für den Guest-Dienst)
successurl URL, an die im Erfolgsfall eine Weiterleitung durchgeführt wird
failureurl URL, an die im Fehlerfall eine Weiterleitung durchgeführt wird

/auth/logout

Loggt den aktuellen Benutzer aus und führt eine HTTP-Weiterleitung an die vorherige Seite durch.

/auth/

Es werden Informationen zum aktiven Login geliefert. Falls kein Benutzer eingeloggt ist, wird ein HTTP-401-Fehler ausgelöst.

JSON-Attribute

username Name des eingeloggten Benutzers
type verwendeter Login-Dienst (Achtung: ldap statt cas)

Cross-Origin-Requests mit Webbrowsern

Webbrowser blocken aus Sicherheitsgründen standardmäßig AJAX-Anfragen an fremde Domains. Für Applikationen, die unter homepages[-fb].thm.de bereitgestellt werden, sind allerdings GET-Anfragen unter der Verwendung von Cross-origin resource sharing[CORS 1][CORS 2] freigeschaltet. CORS legt fest, dass vor dem eigentlichen Request ein zusätzlicher HTTP-OPTIONS-Request vom Browser gesendet wird, der die Domainberechtigungen abfragt. Der Server antwortet, sofern eine entsprechende Implementierung vorliegt, mit Access-Control-Allow-*-Headern, anhand denen der Browser entscheidet, ob er den eigentlichen Request durchgehen lässt. Auf Clientseite (JavaScript) ist keine spezielle Implementierung erforderlich. Die entsprechenden Headerzeilen werden vom Browser, sofern er CORS implementiert, automatisch gesendet.

Anmerkung 07.03.

Momentan werden die benötigten CORS-Header nicht vom Server gesendet. Dies sollte jedoch heute behoben werden. In der Zwischenzeit muss auf einen Workaround zurückgegriffen werden (nächster Abschnitt).

Same Origin Policy deaktivieren

Zu Testzwecken kann die Same Origin Policy vorübergehend im Browser deaktiviert werden. Bis zum Neustart des Browser sollte mit diesem dann aber aufgrund deaktivierter Sicherheitseinstellungen auf keinen Fall fremde Websites aufgerufen werden.

Chrome mit Parameter --disable-web-security starten
Safari (Mac) open -a '/Applications/Safari.app' --args --disable-web-security

Socket.IO

Um wiederholte HTTP-Anfragen für Echtzeitdaten (HTTP-Polling) zu vermeiden, wird für die Abfrage und Änderung dieser Socket.IO[SIO 1] verwendet. Die Adresse des Socket.IO-Servers kann über /socket/url abgefragt werden. Nach der Öffnung eines Websockets muss die Socket-ID an ARSnova übergeben werden, damit dieser dem aktuell eingeloggten Benutzer zugewiesen wird. Dies geschieht über einen POST-Request an /socket/assign mit der Übergabe des Attributs session[SIO 2] eines JSON-Objekts im HTTP-Body. Socket.IO wird in ARSnova für die Feedback-Daten genutzt.

  1. nutzt HTML5-Websockets, falls vom Browser unterstützt; Fallbacks: Flashsockets, XHR-Polling
  2. Nicht zu verwechseln mit ARSnova sessions! Sollte ggf. umbenannt werden (z.B. socketId).

Events (empfangene Daten)

Data Events

Diese Events teilen mit, dass sich Daten geändert haben. Die aktuellen Daten werden mit dem Event gesendet.

activeUserCountData[SIO events 1] text/plain Informs about the count of currently active users in the active session.
feedbackData[SIO events 2] application/json, int[4] Informs about the feedback data for the active session.

Data Available Events

Diese Events teilen mit, das neue Daten verfügbar sind, welche über die REST-API abgefragt werden können. Es wird nur die ID des entsprechenden Datensatzes mitgesendet. Bisher werden diese Events von den existierenden ARSnova-Clients (ARSnova ST1, ARSnova Dojo) noch nicht ausgelöst.

answersToLecQuestionAvail text/plain New answers to a LecturerQuestion are available.
lecQuestionAvail text/plain A LecturerQuestion has been created or updated.
audQuestionAvail text/plain An AudienceQuestion has been created or updated.

Sonstige Events

feedbackReset text/plain The user's feedback has been reset.
  1. Changed event name from updateActiveUserCount (09.03.).
  2. Changed event name from updateFeedback (09.03.).

JSON-Strukturen zum Senden

Die Objektstrukturen sind bisher nicht stabil. Es ist möglich, dass noch Änderungen vorgenommen werden.

setSession

keyword int

setFeedback

sessionkey String
feedback int[4]

Beispiele

API-Zugriffe auf arsnova.thm.de können zum Testen mithilfe des Programms openssl (auf Linux- und Mac-Systemen in der Regel standardmäßig installiert) durchgeführt werden.

Verwendung:

openssl s_client -connect localhost:443

Da das Zeitfenster für Dateneingaben sehr kurz ist, empfiehlt es sich, die Requestdaten vorher anzulegen, um sie nur noch einfügen zu müssen.

Abfrage der besuchten Sessions

HTTP-Request

GET /session/?visitedonly=true&user=sometestuser HTTP/1.1
Host: arsnova.thm.de
Accept: application/json
Cookie: <authentication cookie data>

HTTP-Response

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

[
  {
    "type":"session",
    "name":"web-engeneering-test",
    "shortName":"we-test1",
    "keyword":"123654",
    "creator":"sometestcreator",
    "active":true,
    "lastOwnerActivity":1362473211425,
    "courseType":"",
    "courseId":"",
    "_id":"4ea409f9315816d5b697109b8b0325f8",
    "_rev":"860-0ff2951029a9b836bb865cb58f42d350",
    "courseSession":false
  }
]

Das JSON-Objekt wurde, um die Lesbarkeit zu verbessern, formatiert.

Socket.IO

Für das folgende Beispiel wird vorausgesetzt, dass der Benutzer bereits authentifiziert ist. Ohne gültige Authentifizierung schlägt der POST-Request an /socket/assign fehl.

// AJAX request to /socket/url which returns the URL
// of the Socket.IO server in the HTTP body
var socketIoUrl = [...];

var socketConn = io.connect(socketIoUrl);
socketConn.on("connect", function() {
        console.log("Socket.IO: connected");

        // AJAX POST request to /socket/assign
        // which sends the socket's sessionId
        // (socketConn.socket.sessionid)
        [...]

        // set active ARSnova session
        var sessionKeyword = [...];
        socketConn.emit("setSession", {keyword: sessionKeyword});
});

// Set up data event listeners
socketConn.on("updateActiveUserCount", function(activeUserCount) {
        console.log("Socket.IO: updateActiveUserCount event received");
        console.log(activeUserCount);
});
socketConn.on("updateFeedback", function(feedback) {
        console.log("Socket.IO: updateFeedback event received");
        console.log(feedback);
});