2016-12-22 2 views
5

Ich verwende graphql-server-express, um einen GraphQL-Server zu erstellen, der eine REST-API verwendet.GraphQL-Umleitung, wenn der Resolver Fehler auslöst

Ich bin in der Situation, dass ein REST-Aufruf einen 301- oder 401-Statuscode zurückgeben kann, wenn der Benutzer für den Zugriff auf die Ressource nicht authentifiziert ist. Ich verwende ein Cookie, das auf dem Client festgelegt und während der Auflösung der GraphQL-Abfrage an die REST-API weitergeleitet wird.

Ist es möglich, eine 301-Weiterleitung an den Client als Reaktion auf einen Aufruf des GraphQL-Endpunkts zu senden, wenn ein solcher Fehler auftritt?

Ich habe so etwas wie res.sendStatus(301) … in formatError versucht, aber das funktioniert nicht gut, wie graphql-server-express versucht, Header nach diesem zu setzen.

Ich habe auch versucht, versucht kurzzuschließen die graphqlExpress Middleware mit etwas wie folgt aus:

export default graphqlExpress((req, res) => { 
    res.sendStatus(301); 
    return; 
}); 

Während der Client das korrekte Ergebnis erhält der Server noch Fehler druckt (in diesem Fall TypeError: Cannot read property 'formatError' of undefined - die meisten wahrscheinlich, weil die Middleware leere Optionen erhält).

Gibt es eine gute Möglichkeit, wie dies funktioniert? Vielen Dank!

+0

Umleiten zu wo? Redirect in GraphQL macht keinen Sinn. Was ist, wenn der Client eine Abfrage mit zwei Wurzelknoten sendet, einer erfolgreich ist (keine Anmeldung erforderlich) und einer fehlschlägt, was senden Sie, 300 oder 200? –

+0

Wenn mindestens ein Feld fehlschlägt, sollte in meinem Fall eine Weiterleitung gesendet werden. – amann

+0

Aber graphql Abfragen werden von JS-Code ausgeführt, nicht von Browser direkt, nur das Senden der Umleitung bedeutet nicht, dass der Browser die Anmeldeseite lädt. Ihr graphql-Client muss diesen Antwortcode erkennen und dann hardcoded sein, um etwas zu tun, wenn es passiert. –

Antwort

4

Hier ist, wie ich dies implementiert habe.

Auf der Serverseite:

// Setup 
export default class UnauthorizedError extends Error { 
    constructor({statusCode = 401, url}) { 
    super('Unauthorized request to ' + url); 
    this.statusCode = statusCode; 
    } 
} 

// In a resolver 
throw new UnauthorizedError({url}); 

// Setup of the request handler 
graphqlExpress(async (req, res) => ({ 
    schema: ..., 
    formatError(error) { 
    if (error.originalError instanceof UnauthorizedError) { 
     res.status(error.originalError.statusCode); 
     res.set('Location', 'http://domain.tld/login'); 
    } else { 
     res.status(500); 
    } 

    return error; 
    }, 
}); 

Auf der Clientseite:

const networkInterface = createNetworkInterface(); 

networkInterface.useAfter([{ 
    applyAfterware({response}, next) { 
    if ([401, 403].includes(response.status)) { 
     document.location = response.headers.get('Location'); 
    } else { 
     next(); 
    } 
    } 
}]); 

In Apollo Client 2.0, können Sie wahrscheinlich apollo-link-error auf der Client-Seite für diese.

Verwandte Themen