Apollo-link-rest: Empfohlene Strategie zur Behandlung von 404-Fehlern?

Erstellt am 6. Juni 2018  ·  12Kommentare  ·  Quelle: apollographql/apollo-link-rest


Es ist durchaus üblich, dass eine REST-API eine 404-Antwort verwendet, um anzuzeigen, dass kein Datensatz vorhanden ist. In diesem Fall ist das Ergebnis ein networkError , der standardmäßig als schwerwiegenderer Fehler als ein GraphQL-Fehler des Apollo-Stacks behandelt wird.

Zum Beispiel mit der Abfrage:

query BookQuery($slug: ID!) {
  book(slug: $slug) @rest(type: "Book", path: "book/:slug") {
    name
    author
  }
}

Wenn der Endpunkt 404 zurückgibt, wird er mit einem Netzwerkfehler zurückgewiesen, der behandelt werden muss, wenn die Absicht wahrscheinlich lediglich die Render-Requisite error um einem Benutzer die nicht schwerwiegende Fehlermeldung anzuzeigen. Wenn dies also eine GraphQL-Abfrage anstelle von REST wäre, würde dies nicht als Netzwerkfehler klassifiziert und auf diese Weise behandelt.

Um dies zu beheben, habe ich meinem benutzerdefinierten error-link einen Scheck hinzugefügt, der den 404-Netzwerkfehler in einen GraphQL-Fehler umwandelt:

forward(operation).subscribe({
  next: result => {...},
  error: networkError => {
    if (networkError.statusCode === 404) {
      return observer.next({errors: [networkError]});
    }
    //...
    observer.error(networkError);
  },
  complete: observer.complete.bind(observer),
});

Es gibt wahrscheinlich noch Verbesserungspotenzial, aber es löst das Problem.

Ich habe mich gefragt, ob dies in apollo-link-rest irgendwie angegangen werden könnte / sollte, also dachte ich mir, ich würde das Gespräch beginnen.

enhancement💡 question❔

Alle 12 Kommentare

Das ist eine gute Frage. - Ich würde dieses Muster gerne als Vorschlag zur Dokumentation hinzufügen. Ich denke, es ist eine Klasse von Problemen, unter denen mehrere Apollo-Links leiden (der Apollo-Link-Zustand fällt mir ein).

Ich weiß nicht, ob wir sicher sind, dass dies die richtige Antwort für alle Benutzer von ApolloLink ist.

So werden derzeit alle http-Fehler in apollo-link-rest behandelt

        if (res.status >= 300) {
          // Throw a JSError, that will be available under the
          // "Network error" category in apollo-link-error
          let parsed: any;
          try {
            parsed = await res.json();
          } catch (error) {
            // its not json
            parsed = await res.text();
          }
          rethrowServerSideError(
            res,
            parsed,
            `Response not successful: Received status code ${res.status}`,
          );
        }
        return res;

Vielleicht fügen wir eine Case Matching-Funktion hinzu, mit der Benutzer bestimmen können, wie der Fehler verarbeitet wird.
Könnte einige hilfreiche Standarddienstprogramme für häufige Fälle wie 404 == null bereitstellen

Während ich die Besorgnis von @fbartho teile , dass eine von uns eingeführte Lösung möglicherweise nicht für alle Benutzer dieses Links

query postAndTags {
  post @rest(type: "Post", path: "/post/1") {
    id
    title
  }
  tags @rest(type: "[Tag]", path: "/tags") {
    name
  }
}

und das post existiert nicht und gibt einen 404 zurück, dann schlägt die gesamte Abfrage bei einem Netzwerkfehler fehl. Während dies in einigen Fällen möglicherweise erwünscht sein könnte, scheint das Ergebnis eher zu sein:

const data = {
  post: null,
  tags: [{ name: 'apollo' }, { name: 'graphql' }],
}

Wenn wir dies berücksichtigen möchten, ist das Hinzufügen einer zusätzlichen Fehlerbehandlung, wie von null .

Es bleibt die Frage, ob es sinnvoll ist, einen festen Handler für diese Fehler bereitzustellen, oder ob er der error-link oder der Anwendung überlassen werden sollte. Da mehrere Mutationsabfragen nicht unterstützt werden (glaube ich?), Ist das einzige aktuelle Manko, das besonders relevant erscheint, das 404-Beispiel, mit dem ich oben begonnen habe.

Es gibt auch die Möglichkeit, der Konfiguration einen Fehlerbehandler hinzuzufügen, aber das scheint, als würde dies die Funktionalität eines error-link stehlen, der wirklich dorthin gehört. Es kann auch dazu führen, dass die API dieses Links unnötig komplex wird.

@marnusw Das ist eine großartige Antwort. Ich würde einen Fix unterstützen, der Ihr Verhalten standardmäßig implementiert!

142 fügt 404 Fehlerbehandlung hinzu. Ich denke, das ist das Wichtigste aus dieser Diskussion.

Basierend auf vielen Rest-API- Standards sollten alle Fehlercodes immer eine für Menschen lesbare Nachricht enthalten. Das Nullstellen dieses Ergebnisses, wie es in # 142 getan wurde, steht in direktem Widerspruch dazu.

Ich habe eine PR eingerichtet, um 404 als normale Netzwerkfehler wiederherzustellen, um mit den guten REST-API-Praktiken übereinzustimmen :

@christrude Obwohl ich Ihnen in Bezug auf REST-APIs nicht widersprechen kann, besteht der Zweck dieser Bibliothek darin, REST-APIs wie GraphQL funktionieren zu lassen. Wenn der GraphQL-Ansatz für fehlende Ressourcen darin besteht, null , sollte diese Bibliothek die RESTful 404-Konvention in die GraphQL null Rückgabewertkonvention konvertieren.

@christrude Obwohl ich Ihnen in Bezug auf REST-APIs nicht widersprechen kann, besteht der Zweck dieser Bibliothek darin, REST-APIs wie GraphQL funktionieren zu lassen. Wenn der GraphQL-Ansatz für fehlende Ressourcen darin besteht, null , sollte diese Bibliothek die RESTful 404-Konvention in die GraphQL null Rückgabewertkonvention konvertieren.

Wie schlägt GraphQL dann vor, dass Sie mit einer 404-Antwort in der Benutzeroberfläche umgehen? Nichts tun? Also sterben Anfragen einfach leise? Das ist unglaublich schlechtes / schlechtes UX / API-Management.

Wenn Sie ein Element nach ID abfragen und Null zurückerhalten, behandeln Sie dies in der Benutzeroberfläche entsprechend. Wenn es Daten enthält, zeigen Sie diese an.

Ich stimme @marnusw hier zu, wir können nicht wirklich steuern, was die Rest-API des Benutzers tut, daher sollte die Bibliothek nicht zu restriktiv sein, was sie erlaubt. Die 404 => Null-Zuordnung ist eine relativ intuitive Semantik, mit der Sie von der Einzelressource pro Anforderungsmodell von REST zur Mehrfachressource pro Anforderung (aus Client-Sicht) von GraphQL wechseln können, ohne fehlende Daten in die Luft zu jagen.

Möglicherweise gibt es eine bessere Möglichkeit, dieses Verhalten zu deaktivieren, z. B. eine vorgefertigte Version des Antworttransformators oder eine Abstraktion der Anforderungsbearbeitungslogik, mit der der Benutzer die Behandlung des http-Status vollständig steuern kann. Aber ich denke nicht, dass es der richtige Ansatz ist, zum vorherigen Verhalten zurückzukehren.

Ein Teil des Problems des Ansatzes besteht darin, dass Sie im Ergebnisabonnement nicht wissen, ob es sich um ein Nullergebnis handelt, weil es ein 404 ist, oder ob es sich um eine Rückgabe ohne Inhalt 201 oder ähnliches handelt. Ich habe dies in der Afterware behoben, indem ich den Status überprüfe und erzwinge, einen Fehler auszulösen, der das Problem annimmt, da ich nicht auf die eigentliche Serverfehlermeldung zugreifen kann, insbesondere in meinem Fall, weil wir den benutzerdefinierten Abruf zum Einfügen eines Authentifizierungstokens verwenden und kann es nicht verwenden, um die Antwort zu erhalten, bevor Apollo sie löscht. Meine Lösung ist eine schlechte Decke für andere 404-Antworten in der gesamten App, abgesehen von dem einen Fall.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen