Feathers: REST-Client: Akzeptieren Sie Daten oder Body-Parameter für schwere GET-Anforderungen

Erstellt am 27. Mai 2019  ·  3Kommentare  ·  Quelle: feathersjs/feathers

Hallo,

Ich hatte einige Probleme mit langen URLs in GET-Anfragen. Ich muss in einigen meiner Suchabfragen eine lange Liste von Parametern übergeben.

Die aktuelle Lösung besteht darin, eine neue Middleware und Methodenüberschreibung zu erstellen.

// allow x-http-method-override header for GET methods
exports.default = function (req, res, next) {
    if (req.headers['x-http-method-override'] === 'GET' && req.method === 'POST') {
        req.method = 'GET';
        req.query = req.body;
        delete req.body;
    }
    next();
};

Dann konsumiere ich meinen Dienst wie folgt:

await awesomeService.create(
          {
             someParam: aVeryLongArray // will replace req.query server side thanks to the middleware, and thus bypass URL limitations of browsers
          },
          {
            headers: {
              "x-http-method-override": "GET" // tell the server that this is actually a GET request, so it triggers our middleware
            }
          }
        );

Vielen Dank an Sebastian für die Hilfe bei Slack (ich kann Ihren GitHub-Handle nicht finden, tut mir leid).

Laut dieser SO-Antwort ist dies ein gültiges Muster, da das POST-HTTP-Wort nicht auf die Erstellung per se beschränkt ist, sondern auch mit jeder anderen Art von Aktion verbunden ist, die nicht klassifiziert werden kann. Daher könnte ein "stark parametrisierter Fund" als relevanter Anwendungsfall für POST in Betracht gezogen werden.

Aber ... das Problem ist, dass POST-Anforderungen in Feathers stark an eine "Erstellungs" -Aktion gebunden sind. Bei Verwendung des REST-Clients bedeutet dies, dass wir die create -Methode verwenden müssen, um störende Daten zu finden, und serverseitig bedeutet dies, dass die entsprechende Berechtigung für den create -Hook gesetzt wird, was ebenfalls der Fall ist verstörend.

Ich schlage vor, das Feld body oder data in der GET-Anfrage zu unterstützen (also die Methoden get und find ). Ich denke, die Implementierung ist trivial (und ich würde mich über PR freuen), aber ich frage mich:

  • wenn es eine gute Idee ist (hauptsächlich in Bezug auf Browser, können sie das data - oder body -Feld in der Get-Anfrage streichen?)
  • Was wäre das beste Muster (ein body -Parameter, ein data -Parameter?)

Hilfreichster Kommentar

Ich habe darüber nachgedacht, den REST-Client etwas flexibler zu gestalten, damit Sie Ihre eigenen angepassten Client-Services einfacher instanziieren können. Durch das Zulassen von POST-Abfragen mit JSON würden auch alle URL-String-Konvertierungs- und Array-Parsing-Grenzen vermieden. Im Moment sieht das Anpassen eines REST-Dienstes auf dem Client so aus (so können Sie auch verschiedene Endpunkte verwenden):

const FetchService = require('@feathersjs/rest-client/lib/fetch');

class MyFetchService extends FetchService {
  get (id, params = {}) {
    if (typeof id === 'undefined') {
      return Promise.reject(new Error(`id for 'get' can not be undefined`));
    }

    return this.request({
      url: this.makeUrl({}, id),
      method: 'POST',
      data: params.query,
      headers: Object.assign({
        'x-http-method-override': 'GET'
      }, params.headers)
    }, params).catch(toError);
  }
}

app.use('/someservice', new MyFetchService({
  connection: window.fetch,
  name: 'someservice',
  base: 'mybaseUrl',
  options: {}
}));

Eine nicht brechende Änderung könnte es möglich machen, es einfach zu tun

const feathers = require('@feathersjs/feathers');
const rest = require('@feathersjs/rest-client');

const app = feathers();

// Connect to the same as the browser URL (only in the browser)
app.configure(rest({
  base: '/',
  Service: MyFetchService
}));

Alle 3 Kommentare

Ich habe darüber nachgedacht, den REST-Client etwas flexibler zu gestalten, damit Sie Ihre eigenen angepassten Client-Services einfacher instanziieren können. Durch das Zulassen von POST-Abfragen mit JSON würden auch alle URL-String-Konvertierungs- und Array-Parsing-Grenzen vermieden. Im Moment sieht das Anpassen eines REST-Dienstes auf dem Client so aus (so können Sie auch verschiedene Endpunkte verwenden):

const FetchService = require('@feathersjs/rest-client/lib/fetch');

class MyFetchService extends FetchService {
  get (id, params = {}) {
    if (typeof id === 'undefined') {
      return Promise.reject(new Error(`id for 'get' can not be undefined`));
    }

    return this.request({
      url: this.makeUrl({}, id),
      method: 'POST',
      data: params.query,
      headers: Object.assign({
        'x-http-method-override': 'GET'
      }, params.headers)
    }, params).catch(toError);
  }
}

app.use('/someservice', new MyFetchService({
  connection: window.fetch,
  name: 'someservice',
  base: 'mybaseUrl',
  options: {}
}));

Eine nicht brechende Änderung könnte es möglich machen, es einfach zu tun

const feathers = require('@feathersjs/feathers');
const rest = require('@feathersjs/rest-client');

const app = feathers();

// Connect to the same as the browser URL (only in the browser)
app.configure(rest({
  base: '/',
  Service: MyFetchService
}));

Hallo, ich habe auch das gleiche Problem, bei dem die Suchanforderung mehrere Parameter aufnehmen können sollte und wir das URL-Limit erreichen würden. Also habe ich mich bemüht zu sehen, ob ich einen POST und eine Route zu "finden" statt "erstellen" machen kann.

Ich habe versucht, was @eric-burel vorgeschlagen hat, indem ich den Typ der HTTP-Anforderungsmethode von POST auf GET überschrieb, aber es schlägt fehl, die Methode "create" im Dienst zu finden, anstatt zu "find" zu leiten. Ich habe überprüft, dass die Anforderungsobjektmethode tatsächlich in "GET" geändert wird, aber vielleicht erfolgt das Feather-Routing vor dieser Änderung?

app.use('/appointments', function(req, res, next) {
if (req.method === 'POST') { // Tun dies nur für diesen Dienst.
req.method = 'GET';
req.query = req.body;
Anforderungstext löschen;
}
nächste();
}, {
find: function(params, callback) {
// etwas tun
}
});

Könnte einer von euch bitte klarstellen, ob ich hier etwas vermisse? Oder noch besser, lassen Sie mich wissen, ob es einen besseren Weg gibt, dies zu tun?

Dies kann mit den neuen benutzerdefinierten Methoden (https://github.com/feathersjs/feathers/issues/1976) in Version 5 erfolgen

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen