Feathers: Client REST : accepte les paramètres de données ou de corps pour les requêtes GET lourdes

Créé le 27 mai 2019  ·  3Commentaires  ·  Source: feathersjs/feathers

Salut,

J'ai eu quelques problèmes avec les URL longues dans les requêtes GET. J'ai besoin de passer une longue liste de paramètres dans certaines de mes requêtes "trouver".

La solution actuelle consiste à créer un nouveau middleware et à remplacer les méthodes.

// 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();
};

Ensuite, je consomme mon service comme ceci :

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
            }
          }
        );

Merci beaucoup à Sebastian pour l'aide sur Slack (je ne trouve pas votre pseudo GitHub désolé).

Selon cette réponse SO, il s'agit d'un modèle valide car le mot HTTP POST n'est pas limité à la création en soi, mais également associé à tout autre type d'action qui ne peut pas être classé. Ainsi, une "recherche fortement paramétrée" pourrait être considérée comme un cas d'utilisation pertinent pour POST.

Mais... le problème est que dans Feathers les requêtes POST sont fortement liées à une action de "création". Lorsque vous utilisez le client REST, cela signifie que nous devons utiliser la méthode create pour trouver des données, ce qui est dérangeant, et côté serveur, cela signifie définir l'autorisation appropriée sur le hook create , qui est également inquiétant.

Je propose de prendre en charge le champ body ou data dans la requête GET (donc les méthodes get et find ). Je pense que la mise en œuvre est triviale (et je serais heureux de PR), mais je me demande:

  • si c'est une bonne idée (principalement en ce qui concerne les navigateurs, peuvent-ils supprimer le champ data ou body dans la requête get ?)
  • quel serait le meilleur modèle (un body , un paramètre data ?)

Commentaire le plus utile

J'ai pensé à rendre le client REST un peu plus flexible afin que vous puissiez plus facilement instancier vos propres services client personnalisés. Autoriser les requêtes POST avec JSON éviterait également toutes les limites de conversion de chaîne d'URL et d'analyse de tableau. Pour le moment, la personnalisation d'un service REST sur le client ressemble à ceci (c'est également ainsi que vous pouvez utiliser différents points de terminaison) :

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: {}
}));

Un changement ininterrompu pourrait permettre de faire simplement

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
}));

Tous les 3 commentaires

J'ai pensé à rendre le client REST un peu plus flexible afin que vous puissiez plus facilement instancier vos propres services client personnalisés. Autoriser les requêtes POST avec JSON éviterait également toutes les limites de conversion de chaîne d'URL et d'analyse de tableau. Pour le moment, la personnalisation d'un service REST sur le client ressemble à ceci (c'est également ainsi que vous pouvez utiliser différents points de terminaison) :

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: {}
}));

Un changement ininterrompu pourrait permettre de faire simplement

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
}));

Salut, j'ai aussi le même problème, où la requête de recherche devrait pouvoir accepter plusieurs paramètres, et nous atteindrions la limite d'URL. J'ai donc eu du mal à voir si je pouvais faire un POST et acheminer vers "trouver" au lieu de "créer".

J'ai essayé ce que @eric-burel a suggéré, en remplaçant le type de méthode de requête HTTP de POST à ​​GET, mais il échoue en essayant de trouver la méthode "create" dans le service au lieu de l'acheminer vers "find". J'ai vérifié que la méthode de l'objet de requête est bien changée en "GET", mais peut-être que le routage des plumes se produit avant ce changement ?

app.use('/appointments', function(req, res, next) {
if (req.method === 'POST') { // Faire cela uniquement pour ce service.
req.method = 'GET';
req.query = req.body ;
supprimer req.body ;
}
suivant();
}, {
trouver : fonction (params, rappel) {
// faire quelque chose
}
});

L'un d'entre vous pourrait-il préciser s'il me manque quelque chose ici ? Ou encore mieux, faites-moi savoir s'il y a une meilleure façon de faire cela ?

Cela peut être fait avec les nouvelles méthodes personnalisées (https://github.com/feathersjs/feathers/issues/1976) à venir v5

Cette page vous a été utile?
0 / 5 - 0 notes