Authentifizieren mit GraphQL
Du kannst dich mit einem personal access token, der GitHub App oder der OAuth app bei der GraphQL-API authentifizieren.
Authentifizieren mit einem personal access token
Um sich mit einem personal access token zu authentifizieren, befolgen Sie die Schritte unter Verwalten deiner persönlichen Zugriffstoken. Die angeforderten Daten bestimmen, welche Bereiche oder Berechtigungen du benötigst.
Wählen Sie beispielsweise die Berechtigung "issues:read" aus, um alle Probleme in den Repositorys zu lesen, auf die Ihr Token Zugriff hat.
Alle fine-grained personal access tokens enthalten Lesezugriff auf öffentliche Repositorys. Um mit einem personal access token (classic) auf öffentliche Repositorys zuzugreifen, wähle den Bereich „public_repo“ aus.
Wenn Ihr Token nicht über die erforderlichen Bereiche oder Berechtigungen zum access einer Ressource verfügt, gibt die API eine Fehlermeldung zurück, die die Bereiche oder Berechtigungen angibt, die Ihr Token benötigt.
Authentifizieren mit einer GitHub App
Wenn du die API im Namen einer Organisation oder eines anderen Benutzers nutzen möchtest, empfiehlt GitHub, dass du eine GitHub App verwendest. Um die Aktivität deiner App zuzuordnen, kannst du deine App als eine App-Installation authentifizieren lassen. Um App-Aktivitäten einemeiner Benutzerin zuzuordnen, kannst du deine App im Namen eines Benutzers bzw. einer Benutzerin authentifizieren. In beiden Fällen generierst du ein Token, das du zur Authentifizierung bei der GraphQL-API verwenden kannst. Weitere Informationen finden Sie unter Registrieren einer GitHub-App und Informationen zur Authentifizierung mit einer GitHub-App.
Authentifizieren mit OAuth app
Um dich mit einem OAuth-Token in einer OAuth app zu authentifizieren, musst du deine OAuth app entweder mit einem Anwendungsablauf im Web oder einem Gerätefluss autorisieren. Anschließend können Sie das Zugriffstoken verwenden, das Sie zum Zugriff auf die API erhalten haben. Weitere Informationen findest du unter Erstellen einer OAuth-App und Autorisieren von OAuth-Apps.
Der GraphQL-Endpunkt
Die REST-API verfügt über zahlreiche Endpunkte. Bei der GraphQL-API bleibt der Endpunkt konstant, unabhängig davon, welchen Vorgang du ausführst. Für GitHub Enterprise Server lautet dieser Endpunkt wie folgt:
http(s)://HOSTNAME/api/graphql
Kommunizieren mit GraphQL
Da GraphQL-Vorgänge aus mehrstufigem JSON bestehen, empfiehlt GitHub die Verwendung der GraphQL-Clients, um GraphQL-Aufrufe auszuführen. Du kannst auch curl oder eine andere HTTP-fähige Bibliothek verwenden.
In REST bestimmen HTTP-Verben den ausgeführten Vorgang. In GraphQL stellst du einen JSON-codierten Textkörper bereit, unabhängig davon, ob du eine Abfrage oder eine Mutation ausführst; daher lautet das HTTP-Verb POST. Die Ausnahme ist eine Introspektionsabfrage, die für den Endpunkt einfach GET ist. Weitere Informationen zu GraphQL im Vergleich zu REST finden Sie unter Migrieren von REST zu GraphQL.
Zur Abfrage von GraphQL mit einem curl-Befehl sendest du eine POST-Anforderung mit JSON-Nutzdaten. Die Nutzlast muss eine Zeichenfolge namens query enthalten:
curl -H "Authorization: bearer TOKEN" -X POST -d " \
{ \
\"query\": \"query { viewer { login }}\" \
} \
" http(s)://HOSTNAME/api/graphql
Hinweis
Der Zeichenfolgenwert von "query" muss für Neue-Zeile-Zeichen ein Escapezeichen verwenden, anderenfalls wird das Schema nicht ordnungsgemäß analysiert. Verwende für den POST-Text äußere doppelte Anführungszeichen und innere doppelte Anführungszeichen mit Escapezeichen.
Informationen zu Abfrage- und Mutationsvorgängen
Die beiden Typen zulässiger Vorgänge in der GraphQL-API von GitHub sind queries und mutations. Wenn GraphQL mit REST verglichen wird, funktionieren Abfragen wie GET-Anforderungen, während Mutationen wie POST/PATCH/DELETE funktionieren. Der Mutationsname bestimmt, welche Änderung ausgeführt wird.
Weitere Informationen zur Ratenbegrenzung findest du unter Ratenbegrenzungen und Abfragegrenzwerte für die GraphQL-API.
Abfragen und Mutationen weisen ähnliche Strukturen auf, allerdings mit einigen wichtigen Unterschieden.
Informationen zu Abfragen
GraphQL-Abfragen geben nur die von dir angegebenen Daten zurück. Beim Erstellen einer Abfrage musst du Felder in Feldern (auch als geschachtelte Unterfelder bezeichnet) angeben, bis nur noch Skalare zurückgegeben werden.
Abfragen sind wie folgt strukturiert:
query {
JSON-OBJECT-TO-RETURN
}
Ein reales Beispiel findest du unter Beispielabfrage.
Informationen zu Mutationen
Zum Erstellen einer Mutation musst du drei Dinge angeben:
-
_Mutationsname_. Die Art der Änderung, die du ausführen möchtest. -
_Eingabeobjekt_. Die Daten, die du an den Server senden möchtest, bestehen aus _Eingabefeldern_. Übergib es als Argument an den Mutationsnamen. -
_Nutzlastobjekt_. Die Daten, die du vom Server zurückgeben möchtest; sie bestehen aus _Rückgabefeldern_. Übergib sie als Körper des Mutationsnamens.
Mutationen sind wie folgt strukturiert:
mutation {
MUTATION-NAME(input: {MUTATION-NAME-INPUT!}) {
MUTATION-NAME-PAYLOAD
}
}
Das Eingabeobjekt in diesem Beispiel lautet MutationNameInput, und das Nutzlastobjekt ist MutationNamePayload.
In der Mutationsreferenz sind die aufgeführten Eingabefelder das, was du als Eingabeobjekt übergibst. Die aufgeführten Rückgabefelder sind das, was du als Nutzlastobjekt übergibst.
Ein reales Beispiel findest du unter Beispielmutation.
Arbeiten mit Variablen
[Variablen](https://graphql.org/learn/queries/#variables) können Abfragen dynamischer und leistungsfähiger machen, und sie können die Komplexität beim Übergeben von Mutationseingabeobjekten verringern.
Nachfolgend findest du eine Beispielabfrage mit einer einzelnen Variable:
query($number_of_repos:Int!) {
viewer {
name
repositories(last: $number_of_repos) {
nodes {
name
}
}
}
}
variables {
"number_of_repos": 3
}
Es gibt drei Schritte zum Verwenden von Variablen:
-
Definiere die Variable außerhalb des Vorgangs in einem
variables-Objekt:variables { "number_of_repos": 3 }Das Objekt muss gültiger JSON-Code sein. In diesem Beispiel wird ein einfacher
Int-Variablentyp dargestellt, aber es ist möglich, komplexere Variablentypen wie Eingabeobjekte zu definieren. Du kannst hier auch mehrere Variablen definieren. -
Übergib die Variable als Argument an den Vorgang:
query($number_of_repos:Int!){Das Argument ist ein Schlüssel-Wert-Paar, wobei der Schlüssel der Name ist, der mit
$beginnt (z. B.$number_of_repos), und der Wert der Typ (z. B.Int). Gib zusätzlich mit!an, ob der Typ erforderlich ist. Wenn du mehrere Variablen definiert hast, füge sie hier als mehrere Argumente ein. -
Verwende die Variable innerhalb des Vorgangs:
repositories(last: $number_of_repos) {In diesem Beispiel ersetzen wir die Variable für die Anzahl der Repositorys, die abgerufen werden sollen. Wir geben einen Typ in Schritt 2 an, da GraphQL strenge Typisierung erzwingt.
Dieser Prozess macht das Abfrageargument dynamisch. Wir können nun einfach den Wert im variables-Objekt ändern und den Rest der Abfrage unverändert lassen.
Mithilfe von Variablen als Argumente kannst du Werte im variables-Objekt dynamisch aktualisieren, ohne die Abfrage zu ändern.
Beispielabfrage
Gehe die folgende komplexere Abfrage durch, die diese Informationen in einen Kontext einbindet.
Die folgende Abfrage durchsucht das Repository octocat/Hello-World, findet die 20 zuletzt geschlossenen Issues und gibt jeweils den Titel, die URL und die ersten 5 Labels zurück.
query {
repository(owner:"octocat", name:"Hello-World") {
issues(last:20, states:CLOSED) {
edges {
node {
title
url
labels(first:5) {
edges {
node {
name
}
}
}
}
}
}
}
}
Sieh dir Zeile für Zeile an, wie sie zusammengesetzt ist:
-
query {Dein Ziel ist es, Daten vom Server zu lesen und nicht zu ändern. Daher lautet der Stammvorgang
query. (Wenn du keinen Vorgang angibst, istqueryauch die Standardeinstellung.) -
repository(owner:"octocat", name:"Hello-World") {Zu Beginn der Abfrage soll das
repository-Objekt gesucht werden. Die Schemavalidierung gibt an, dass dieses Objekt einowner-Argument und einname-Argument erfordert. -
issues(last:20, states:CLOSED) {Damit alle Issues im Repository berücksichtigt werden, rufen wir das
issues-Objekt auf. (Wir könnten ein einzelnesissuein einemrepositoryabfragen, aber das erfordert, dass wir die Nummer des Issues kennen, das wir zurückgeben möchten, und diese als Argument angeben.)Einige Details zum
issues-Objekt:- Die Dokumentation gibt an, dass dieses Objekt den Typ
IssueConnectionaufweist. - Die Schemavalidierung gibt an, dass dieses Objekt eine letzte (
last) oder erste (first) Nummer der Ergebnisse als Argument erfordert. Daher geben wir20an. - Die Dokumentation gibt auch an, dass dieses Objekt ein
states-Argument akzeptiert, das eineIssueState-Enumeration ist, dieOPEN- oderCLOSED-Werte akzeptiert. Damit nur geschlossene Issues gesucht werden, erhält der Schlüsselstatesden WertCLOSED.
- Die Dokumentation gibt an, dass dieses Objekt den Typ
-
edges {Wir wissen, dass
issueseine Verbindung ist, da es den TypIssueConnectionaufweist. Um Daten zu einzelnen Problemen abzurufen, müssen wir überedgesauf den Knoten zugreifen. -
node {Hier rufen wir den Knoten am Ende der Kante ab. Die
IssueConnection-Dokumentation gibt an, dass der Knoten am Ende desIssueConnection-Typs einIssue-Objekt ist. -
Nachdem nun bekannt ist, dass wir ein
Issue-Objekt abrufen, können wir anhand der Dokumentation die Felder angeben, die zurückgegeben werden sollen:title url labels(first:5) { edges { node { name } } }Hier geben wir die Felder
title,urlundlabelsdesIssue-Objekts an.Das Feld
labelsbesitzt den TypLabelConnection. Wie beimissues-Objekt müssen wir, dalabelseine Verbindung ist, über die Kanten zu einem verbundenen Knoten gelangen: demlabel-Objekt. Auf dem Knoten können wir dielabel-Objektfelder angeben, die zurückgegeben werden sollen, in diesem Fallname.
Du stellst möglicherweise fest, dass die Ausführung dieser Abfrage für das öffentliche Hello-WorldOctocat-Repository nicht viele Bezeichnungen zurückgibt. Versuche, sie auf einem deiner eigenen Repositorys auszuführen, die Bezeichnungen verwenden. Dann wirst du wahrscheinlich einen Unterschied sehen.
Beispielmutation
Mutationen erfordern häufig Informationen, die du nur ermitteln kannst, indem du zuerst eine Abfrage ausführst. In diesem Beispiel werden zwei Vorgänge gezeigt:
- Eine Anfrage zum Abrufen einer Issue-ID.
- Eine Mutation, um einem Problem eine Emoji-Reaktion hinzuzufügen.
query FindIssueID {
repository(owner:"octocat", name:"Hello-World") {
issue(number:349) {
id
}
}
}
mutation AddReactionToIssue {
addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {
reaction {
content
}
subject {
id
}
}
}
Gehen wir das Beispiel durch. Die Aufgabe klingt einfach: Füge einem Thema eine Emoji-Reaktion hinzu.
Woher erkennen wir, dass wir mit einer Abfrage beginnen sollen? Wir wissen es noch nicht.
Da wir Daten auf dem Server ändern möchten (ein Emoji an ein Issue anfügen), durchsuchen wir zu Beginn das Schema nach einer hilfreichen Mutation. Die Referenzdokumentation gibt die addReaction-Mutation mit dieser Beschreibung an: Adds a reaction to a subject. Perfekt!
Die Dokumentation für die Mutation listet drei Eingabefelder auf:
-
`clientMutationId` (`String`) -
`subjectId` (`ID!`) -
`content` (`ReactionContent!`)
Mit ! wird angegeben, dass subjectId und content erforderliche Felder sind. Es ist verständlich, dass content erforderlich ist: Wir möchten eine Reaktion hinzufügen und müssen daher angeben, welches Emoji verwendet werden soll.
Aber warum ist subjectId erforderlich? Es liegt daran, dass nur mit subjectId bestimmt werden kann, auf welches Issue in welchem Repository reagiert werden soll.
Aus diesem Grund beginnen wir dieses Beispiel mit einer Abfrage: um die ID abzurufen.
Sehen wir uns nun die Abfrage Zeile für Zeile an:
-
query FindIssueID {Hier führen wir eine Abfrage aus und nennen sie
FindIssueID. Beachten Sie, dass die Benennung einer Abfrage optional ist; wir geben ihm hier einen Namen, damit wir ihn in das gleiche GUI-Clientfenster wie die Mutation aufnehmen können. -
repository(owner:"octocat", name:"Hello-World") {Wir geben das Repository an, fragen dazu das
repository-Objekt ab und übergeben die Argumenteownerundname. -
issue(number:349) {Wir geben das Issue an, auf das reagiert werden soll, fragen dazu das
issue-Objekt ab und übergeben einnumber-Argument. -
idHier rufen wir den
idvonhttps://github.com/octocat/Hello-World/issues/349ab, um ihn alssubjectIdzu übergeben.
Wenn wir die Abfrage ausführen, erhalten wir die id: MDU6SXNzdWUyMzEzOTE1NTE=
Hinweis
Die in der Abfrage zurückgegebene id ist der Wert, den wir als subjectID in der Mutation übergeben werden. Weder die Dokumentation noch die Schemaintrospektion geben diese Beziehung an; Du musst die Konzepte hinter den Namen verstehen, um dies zu ermitteln.
Mit der bekannten ID können wir mit der Mutation fortfahren:
-
mutation AddReactionToIssue {Hier führen wir eine Mutation aus und nennen sie
AddReactionToIssue. Wie bei Abfragen ist die Benennung einer Mutation optional; wir geben ihm hier einen Namen, damit wir ihn in das gleiche GUI-Clientfenster wie die Abfrage einschließen können. -
addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {Sehen wir uns diese Zeile an:
-
`addReaction` ist der Name der Mutation. -
`input` ist der erforderliche Argumentschlüssel. Dies ist für eine Mutation immer `input`. -
`{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}` ist der erforderliche Argumentwert. Dies ist für eine Mutation immer ein [Eingabeobjekt](/graphql/reference/input-objects) (daher die geschweiften Klammern) aus Eingabefeldern (in diesem Fall `subjectId` und `content`).
Wie wissen wir, welcher Wert für den Inhalt verwendet werden soll? Die
addReactionDokumentation informiert uns, dass dascontent-Feld den TypReactionContenthat, welcher ein enum ist, da nur bestimmte Emoji-Reaktionen bei GitHub-Issues unterstützt werden. Dies sind die zulässigen Werte für Reaktionen (einige Werte weichen von den entsprechenden Emojinamen ab):Inhalt Emoji +1👍 -1👎 laugh😄 confused😕 heart❤️ hooray🎉 rocket🚀 eyes👀 -
-
Der Rest des Aufrufs besteht aus dem Nutzlastobjekt. Hier geben wir die Daten an, die vom Server zurückgegeben werden sollen, nachdem die Mutation durchgeführt wurde. Diese Zeilen stammen aus der
addReaction-Dokumentation und weisen drei mögliche Rückgabefelder auf:-
`clientMutationId` (`String`) -
`reaction` (`Reaction!`) -
`subject` (`Reactable!`)
In diesem Beispiel geben wir die beiden erforderlichen Felder (
reactionundsubject) zurück, die beide über erforderliche Unterfelder verfügen (contentbzw.id). -
Wenn wir die Mutation ausführen, ist dies die Reaktion:
{
"data": {
"addReaction": {
"reaction": {
"content": "HOORAY"
},
"subject": {
"id": "MDU6SXNzdWUyMTc5NTQ0OTc="
}
}
}
}
Das ist alles! Schauen Sie sich Ihre Reaktion auf das Problem an, indem Sie mit der Maus über 🎉 fahren, um Ihren Benutzernamen zu finden.
Ein letzter Hinweis: Wenn du mehrere Felder in einem Eingabeobjekt übergibst, kann die Syntax unübersichtlich werden. Das Verschieben der Felder in eine Variable kann helfen. So kannst du die ursprüngliche Mutation mithilfe einer Variablen neu schreiben:
mutation($myVar:AddReactionInput!) {
addReaction(input:$myVar) {
reaction {
content
}
subject {
id
}
}
}
variables {
"myVar": {
"subjectId":"MDU6SXNzdWUyMTc5NTQ0OTc=",
"content":"HOORAY"
}
}
Hinweis
Du kannst feststellen, dass der content-Feldwert im vorherigen Beispiel (in dem er direkt in der Mutation verwendet wird) keine Anführungszeichen um HOORAY enthält; er enthält jedoch Anführungszeichen, wenn er in der Variablen verwendet wird. Hierfür gibt es einen Grund:
- Wenn du
contentdirekt in der Mutation verwendest, erwartet das Schema für den Wert den TypReactionContent, der eine Enumeration ist, keine Zeichenfolge. Die Schemaüberprüfung löst einen Fehler aus, wenn du Anführungszeichen um den Enumerationswert hinzufügst, da Anführungszeichen für Zeichenfolgen reserviert sind. - Wenn du
contentin einer Variablen verwendest, muss der Abschnitt für die Variablen gültiger JSON-Code sein, und daher sind die Anführungszeichen erforderlich. Die Schemaüberprüfung interpretiert den TypReactionContentrichtig, wenn die Variable während der Ausführung an die Mutation übergeben wird.
Weitere Informationen zum Unterschied zwischen Enumerationen und Zeichenfolgen findest du in der offiziellen GraphQL-Spezifikation.
Weitere Informationen
Beim Erstellen von GraphQL-Aufrufen hast du zahlreiche weitere Möglichkeiten. Weitere Orte, die Sie als Nächstes in Betracht ziehen können:
-
[AUTOTITLE](/graphql/guides/using-pagination-in-the-graphql-api) -
[Fragmente](https://graphql.org/learn/queries/#fragments) -
[Inlinefragmente](https://graphql.org/learn/queries/#inline-fragments) -
[Anweisungen](https://graphql.org/learn/queries/#directives)