Benutzer-Werkzeuge

Webseiten-Werkzeuge


leuris_portal_graphql

leuris:Portal GraphQL-API

GraphQL allgemein

Die im leuris:Forschungsbericht eingetragenen Daten sind im leuris:Portal öffentlich einsehbar. Neben der Darstellung im leuris:Portal selbst besteht außerdem die Möglichkeit, die Daten über eine GraphQL-Schnittstelle zu beziehen. Eine GraphQL-Schnittstelle (oder GraphQL-Endpunkt) erlaubt es durch die Abfragesprache GraphQL Daten bedarfsgerecht abzuholen. Eine ausführliche Erklärung (auf Englisch) liefert die offizielle GraphQL-Dokumentation. GraphQL ist eine typisierte Anfragesprache, d.h. es existiert eine Schema-Definition der Entitäten und ihren Beziehungen. Ein GraphQL-Endpunkt liefert neben den Daten auch Informationen zum (zugehörigen) Schema der Daten.

Queries an das leuris

Queries lassen sich auf zwei Weisen an den leuris-GraphQL-Endpunkt stellen. Zum Experimentieren und Lernen kann ein browserbasierter Editor (GraphiQL) genutzt werden. Dort wird das Schreiben von Queries durch ein Vorschlagssystem unterstützt. Es werden direkt beim Tippen, ähnlich wie bei einer IDE, Vorschläge gemacht. Alternativ lässt sich durch Drücken der Kombination Shift+Leertaste (bzw. Umschalttaste+Leertaste) eine Liste von möglichen Schlüsselwörtern anzeigen. Zusätzlich lässt sich hier auch die Dokumentation bzw. Schema-Definition bequem im Browser anzeigen. Weiterhin können Queries dort auch gespeichert werden und der ganze Workspace kann exportiert (und später importiert) werden.

Eine zweite Möglichkeit zum Stellen von Queries ist das Senden eines POST-Requests an den Endpunkt https://fob.uni-leipzig.de/anchorwheel/api. Dieser Endpunkt erwartet einen JSON-Payload (Content-Type application/json), der im einfachsten Fall so strukturiert ist:

{
  "query": "..."
}

Für eine parametrisierte Query müssen zusätzlich noch Werte für einzelnen Variablen übergeben werden:

{
  "query": "...",
  "variables": {
    "variable1": "wert1",
    "variable2": "wert2",
    ...
  }
}

Informationen zum Schema der leuris-GraphQL-Schnittstelle

Im nächsten Abschnitt werden einige typische Anwendungsfälle vorgestellt. Um die dafür genutzten Queries anzupassen oder um selbst Queries zu schreiben, empfiehlt es sich, die Dokumentation der einzelnen Typen der leuris-GraphQL-Schnittstelle einzusehen. Auf der GraphiQL-Oberfläche (bzw. dem oben erwähnten Editor) unter https://fob.uni-leipzig.de/anchorwheel/graphiql lässt sich diese Dokumentation einsehen.

Alternativ lässt sich das Schema auch programmatisch abfragen. Eine Erklärung dazu findet sich in der offiziellen GraphQL-Dokumentation unter dem Stichwort Introspection und es wird daher an dieser Stelle nicht genauer darauf eingegangen.

Typische Anwendungsfälle

Eine GraphQL-Schnittstelle kann viele verschiedene Anwendungsfälle abdecken. Im Folgenden werden einige davon exemplarisch beschrieben. Zum Testen von Queries kann alternativ auch der (generische) Desktop API-Client Insomnia genutzt werden. Ein Workspace für Insomnia mit den Beispielqueries kann hier heruntergeladen werden:

Profilseite einer Person

Zunächst muss der leuris-Personenidentifier der Person bekannt sein. Ihren eigenen leuris-Identifier sehen sie in der leuris:Profilseite im Kopf.

Eine zweite Möglichkeit bietet die Personensuche im leuris:Portal. Aktuell ist der leuris-Identifier dort jedoch nur aus der URI abzulesen:

https://fob.uni-leipzig.de/public/person/ss26ho39/forschungsprojekt

Hier ist ss26ho39 der leuris-Personenidentifier.

Der leuris-Personenidentifier kann nun genutzt werden, um Daten über diese Person von der leuris-GraphQL-Schnittstelle zu beziehen. Das Grundgerüst sieht dabei wie folgt aus:

query {
  person(id: "ss26ho39") {
    # hier weitere Felder ergänzen
  }
}

Das Antwort-Objekt ist vom Typ „Person“. Wie im vorherigen Abschnitt erwähnt, lassen sich Informationen zu diesem Typ in der Dokumentation der leuris-GraphQL-Schnittstelle nachschlagen. Alternativ können mögliche Felder auch mit dem Vorschlagssystem im GraphiQL angezeigt werden (Shift+Leertaste):

Um z.B. (einige der) Daten zu beziehen, die auch zur Darstellung auf der Uni-Website genutzt werden, kann folgende Query genutzt werden:

query {
  person(id: "ss26ho39") {
    leurisProfile {
      # Kurzbeschreibung zur Person
      abstract {
        de
        en
      }
      # Ausgewählte Forschungsaktivitäten
      researchSelection {
        publications {
          html {
            de
            en
          }
        }
        # kann auch kompakt geschrieben werden
        projects { html { de en } }
        events { html { de en } }
        cooperations { html { de en } }
        awards { html { de en } }
      }
    }
  }
}

Die „researchSelection“ enthält die Publikationen, Projekte, Veranstaltungen, Kooperation und Auszeichnungen, die die Wissenschaftlerin oder der Wissenschaftler auf ihrer oder seiner leuris:Profilseite favorisiert hat. Für eine bequeme Darstellung empfiehlt es sich, direkt eine Kompaktdarstellung in Form eines HTML-Snippets abzuholen. Die genannten Forschungsaktivitäten sind ebenfalls Typen, die durch die leuris-GraphQL-Schnittstelle spezifiziert werden und können viele weitere Attribute herausgeben. Bei Publikationen sind das z.B. Titel und Jahr, ggf. das Projekt, aus dem sie entstanden sind, Autoren bzw. Herausgeber usw. Die Beispielquery von oben kann also z.B. wie folgt abgeändert werden:

query {
  person(id: "ss26ho39") {
    leurisProfile {
      # Kurzbeschreibung ausgelassen
      # Ausgewählte Forschungsaktivitäten
      researchSelection {
        publications {
          title
          authors {
            fullName
          }
        }
        # restliche Forschungsaktivitäten ausgelassen
      }
    }
  }
}

Analog zu den Publikationen können auch bei Autoren weitere Felder abgefragt werden, z.B. Vorname (givenName) und Nachname (surname) getrennt.

Parametrisierte Queries

Soll eine Query mehrfach mit verschiedenen Parametern gestellt werden (etwa programmatisch über einen POST-Request), empfiehlt sich die Verwendung von Variablen. Beispielweise könnte der Payload in einem POST-Request dann so aussehen:

{
  "query": "
    query ($leurisID: ID!) {
      person(id: $leurisID) {
        leurisProfile {
          abstract {
            de
            en
          }
        }
      }
    }
  ",
  "variables": {
    "leurisID": "ss26ho39"
  }
}

:!: Für bessere Lesbarkeit sind in der Query (bzw. genauer: im Wert zum Key „query“) einige Zeilenumbrüche eingefügt. Dies ist so allerdings kein valides JSON, die Query muss in einem String ohne Zeilenumbrüche hinterlegt werden.

Variablen müssen einmal auf der obersten Ebene deklariert werden, zusammen mit dem erwarteten Typ und ob sie optional oder obligatorisch sind (ein Ausrufezeichen hinter dem Typ macht eine Variable obligatorisch):

    query ($leurisID: ID!) { ...

Danach können die Variablen (auch mehrfach) genutzt werden, d.h. sie werden Parametern als Wert übergeben. Im Beispiel also:

      person(id: $leurisID) { ...

Der Vorteil ist, dass die Variablen als einfaches JSON-Objekt übergeben werden können. Die Query selbst ist eine Zeichenkette, die ggf. nicht für jede Anfrage angepasst werden soll. Perspektivisch könnten längere Queries auch über einen Hash identifiziert werden, so dass bei einer Anfrage nur der Hash der Query und die Variablen übergeben werden. Dies ist allerdings zur Zeit noch nicht implementiert.

Alle Forschungsaktivtäten einer Person oder Organisationseinheit

Das Grundgerüst, um alle Forschungaktivitäten einer Person abzufragen, ist ähnlich zu der Query für die leuris:Profilseite weiter oben. Für Organisationen sieht dieses wie folgt aus:

query {
  organisationalUnit(id: 415) {
    # hier weitere Felder
  }
}

Als Argument muss hier eine spezielle leuris-interne ID übergeben werden. Diese lässt sich wieder über den Link im leuris:Portal herausfinden. Der Link zur Fakultät für Mathematik und Informatik ist z.B. https://fob.uni-leipzig.de/public/ou/415/forschungsprojekt. Die ID ist entsprechend 415.

Bei der Abfrage aller Forschungsaktivitäten, z.B. aller Publikationen, ergibt sich das Problem, dass dies sehr viele sein können. Die Ergebnisse werden daher paginiert zurückgeliefert. Dies muss auch in der Query entsprechend berücksichtigt werden:

query {
  organisationalUnit(id: 415) {
    publications(page: 1) {
      entries {
        ... on Publication {
          html {
            de
            en
          }
        }
      }
      meta {
        totalPages
      }
    }
  }
}

Zur Erklärung: Die einzelnen Felder für Forschungsaktivitäten (publications, projects, events, …) liefern in dieser Query nur „Page-Objekte“ zurück. Eine Page ist ein Typ, der die beiden Felder „entries“ und „meta“ enthält. „meta“ liefert dabei u.a. Informationen, wie viele Pages es gibt. Das Feld „entries“ ist hingegeben ein sogenannter Union-Type, der eine Kollektion verschiedener Typen darstellt. Je nach Query können im entries-Feld Objekte des Typs „Publication“, „Project“, usw. zurückgegeben werden. Daher muss bei der Query entsprechend angegeben werden, welcher Typ erwartet wird bzw. welche Felder für welchen Typ gewünscht sind. Dies geschieht durch den Teil

        ... on Publication {
          # hier gewünschte Felder spezifizieren
        }

Das ist ein sogenanntes Inline Fragment.

Prinzipiell kann diese Query auch um Felder für Projekte, Veranstaltungen usw. erweitert werden. Soll hier aber z.B. eine Live-Abfrage direkt beim Blättern auf einer Website geschehen, ist es sinnvoller, nur die Seite für die aktuell angezeigte Aktivität abzuholen.

Im Beispiel oben kommen zwei Felder vor, die Argumente akzeptieren:

query {
  organisationalUnit(id: 415) {
    publications(page: 1) {
       # Hier der Rest der Query
    }
  }
}

Der erste Parameter (id: 415) dient, wie oben erläutert, zur Auswahl der Organisationseinheit. Das Feld „publications“ hat im Beispiel den Parameter page: 1 um die gewünscht Seite auszuwählen. Neben dem „page“-Parameter können weitere Parameter an das Feld „publications“ übergeben werden. Diese Parameter sind auch für die Felder „projects“, „awards“, „events“ und „cooperations“ möglich.

Diese Parameter sind:

  • page: Mit diesem Parameter wird die gewünschte Seite ausgewählt.
  • pageSize: Mit diesem Parameter kann bestimmt werden, wie viele Ergebnisse pro Seite angezeigt werden.
  • orderBy: Mit diesem Parameter kann bestimmt werden, welches Kriterium zum Sortieren benutzt wird. Mögliche Werte sind vorgegeben und variieren von Feld zu Feld. Sie können in der Doku nachgeschlagen oder über die Vorschlagsfunktion im GraphiQL angezeigt werden.

  • sortOrder: Dieser Parameter kann die Werte ASC oder DESC haben für aufsteigende bzw. absteigende Sortierreihenfolge.
  • cumulative: Dies ist ein boolescher Parameter. Standardmäßig ist dieser Parameter auf TRUE gesetzt. Dies bedeutet, dass nicht nur Forschungsaktivitäten zur ausgewählen Organisationseinheit (im Beispiel 415, die Fakultät für Mathematik und Informatik) ausgegeben werden, sondern auch solche, die darunterliegenden Organisationseinheiten zugeordnet sind. Im Fall einer Fakultät bedeutet das, dass auch Forschungsaktivitäten der darunterliegenden Institute (z.B. Mathematisches Institut und Institut für Informatik) sowie auch tieferliegende Organisationseinheiten wie Lehrstühle (z.B. der Lehrstuhl für Algebra oder der Lehrstuhl für Datenbanken) ausgegeben werden.
  • filter: Dieser Parameter erlaubt es, Forschungsaktivitäten nach bestimmten Kriterien zu filtern. Er wird im nächsten Abschnitt genauer beschrieben.

Mit Ausnahme des Parameters „cumulative“ sind alle diese Parameter auch verfügbar, wenn Forschungsaktivitäten für Personen gesucht werden. Folgende (parametrisierte) Query findet Publikation einer Person, geordnet nach dem Jahr, in absteigender Reihenfolge und gibt für jede Publikation Titel und Jahr aus:

query ($leurisID: ID!) {
  person(id: $leurisID) {
    publications(page: 1, orderBy: YEAR, sortOrder: DESC) {
      entries {
        ... on Publication {
          title
          year
        }
      }
    }
  }
}

Auswahl an Forschungsaktivtäten einer Person oder Organisationseinheit

Es wurden bisher zwei Typen von Queries vorgestellt, die alle Forschungsaktivitäten einer Organisationseinheit oder einer Person zurückliefern können. In beiden Fällen wurden dazu die Felder „publications“, „projects“, „awards“, „events“ und/oder „cooperations“ genutzt. Die Felder können als Argument ein Filter-Objekt übergeben bekommen, wodurch genauer bestimmt werden kann, welche Publikationen, Projekte usw. gefunden werden.

Filter-Objekte sind (wie alle anderen GraphQL-Objekte auch) typisiert. Da in Abhängigkeit der Art der Forschungsaktivität verschiedene Filterparameter sinnvoll sind, gibt es dementsprechend PublicationFilter, ProjectFilter, AwardFilter, EventFilter und CooperationFilter.

In allen Filter-Objekten können folgende Keys benutzt werden:

  • year: Es kann ein Jahr übergeben werden, um nur Aktivitäten zu finden, die in diesem Jahr stattgefunden haben bzw. stattfinden.
  • freeText: Ebenfalls gibt es die Möglichkeit einer Freittext-Suche, mit dem in mehreren Textfeldern gleichzeitig gesucht wird (bei Projekten beispielsweise im Projekttitel und der Projektbeschreibung). Die Freitext-Suche berücksichtigt keine Personen.
  • person: Es gibt in allen Filterobjekten den Filterschlüssel „person“. Berücksichtigt werden von diesem Schlüssel alle Personen, die innerhalb einer Aktivität erwähnt werden (bspw. Autoren, Herausgeber, Projektleiter, usw.).

Zusätzlich zu diesen drei Filterschlüsseln gibt es noch folgende (wenn nicht anders angegeben, handelt es sich um Textsuche, die nach Zeichenketten oder Teilen davon sucht):

  • PublicationFilter:
    • category: Filtert nach der Art der Publikation, mögliche Werte sind ARTICLE, CONTRIBUTION, EDITORSHIP, MONOGRAPHY und REPORT.
  • ProjectFilter:
    • status: Erlaubt Filtern nach abgeschlossenen oder laufenden Projekten, mögliche Werte sind ONGOING und TERMINATED.
    • funding: Ermöglicht Filtern nach Mittelgebern. Dies ist zur Zeit noch eine reine Textsuche, soll aber mittelfristig umgestellt werden.
  • AwardFilter:
    • Keine weiteren Schlüssel abgesehen von den drei Standardschlüsseln.
  • EventFilter:
    • Keine weiteren Schlüssel abgesehen von den drei Standardschlüsseln.
  • CooperationFilter:
    • externalPartner: Filtert nach beteiligten (externen) Organisationseinheiten.

Beispiel-Query: Angezeigt werden sollen alle Publikationen von der Fakultät für Mathematik und Informatik (id: 415), die im Jahr 2019 erschienen sind und das Wort „automata“ im Titel enthalten. Zurückgegeben werden soll die Anzahl der Publikationen und die einzelnen Titel. Folgende Query liefert das gewünschte Ergebnis:

query {
  organisationalUnit(id: 415) {
    publications(page: 1, filter: { category:ARTICLE, year: 2019, freeText: "automata" }) {
      entries {
        ... on Publication {
          title
        }
      }
      meta {
        # Anzahl der gefunden Publikationen
        totalEntries
      }
    }
  }
}

Diese Query kann natürlich wie vorher beschrieben angepasst werden und so z.B. HTML-Snippets zurückliefern.

leuris_portal_graphql.txt · Zuletzt geändert: 2020/07/09 14:54 von nareike