Feathers: Cliente REST: Aceite dados ou parâmetros de corpo para solicitações GET pesadas

Criado em 27 mai. 2019  ·  3Comentários  ·  Fonte: feathersjs/feathers

Oi,

Eu tive alguns problemas com URLs longos em solicitações GET. Eu preciso passar uma longa lista de parâmetros em algumas das minhas consultas "find".

A solução atual é criar um novo middleware e substituição de método.

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

Então, eu consumo meu serviço assim:

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

Muito obrigado a Sebastian pela ajuda no Slack (não consigo encontrar seu identificador do GitHub, desculpe).

De acordo com esta resposta do SO, este é um padrão válido porque a palavra POST HTTP não está limitada à criação em si, mas também associada a qualquer outro tipo de ação que não possa ser classificada. Portanto, uma "localização fortemente parametrizada" pode ser considerada um caso de uso relevante para POST.

Mas... o problema é que em Feathers a requisição POST está fortemente ligada a uma ação de "criação". Ao usar o cliente REST, isso significa que devemos usar o método create para encontrar dados, o que é perturbador, e o lado do servidor, o que significa definir a permissão relevante no gancho create , que também é perturbador.

Proponho dar suporte ao campo body ou data na solicitação GET (então métodos get e find ). Eu acho que a implementação é trivial (e eu ficaria feliz em PR), mas eu me pergunto:

  • se for uma boa ideia (principalmente em relação aos navegadores, eles podem descartar o campo data ou body na solicitação de obtenção?)
  • qual seria o melhor padrão (um parâmetro body , um parâmetro data ?)

Comentários muito úteis

Tenho pensado em tornar o cliente REST um pouco mais flexível para que você possa instanciar mais facilmente seus próprios serviços de cliente personalizados. Permitir consultas POST com JSON também evitaria toda a conversão de string de URL e limites de análise de matriz. No momento, a personalização de um serviço REST no cliente se parece com isso (também é assim que você pode usar diferentes endpoints):

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

Uma mudança ininterrupta poderia tornar possível apenas fazer

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

Todos 3 comentários

Tenho pensado em tornar o cliente REST um pouco mais flexível para que você possa instanciar mais facilmente seus próprios serviços de cliente personalizados. Permitir consultas POST com JSON também evitaria toda a conversão de string de URL e limites de análise de matriz. No momento, a personalização de um serviço REST no cliente se parece com isso (também é assim que você pode usar diferentes endpoints):

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

Uma mudança ininterrupta poderia tornar possível apenas fazer

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

Oi, eu também tenho o mesmo problema, onde a solicitação de localização deve ser capaz de receber vários parâmetros e atingir o limite de URL. Então eu tenho lutado para ver se consigo fazer um POST e rotear para "encontrar" em vez de "criar".

Eu tentei o que @eric-burel sugeriu, substituindo o tipo de método de solicitação HTTP de POST para GET, mas ele falha ao tentar encontrar o método "create" no serviço em vez de rotear para "find". Verifiquei que o método do objeto de solicitação está realmente sendo alterado para "GET", mas talvez o roteamento de penas aconteça antes dessa alteração?

app.use('/compromissos', function(req, res, next) {
if (req.method === 'POST') { // Fazendo isso apenas para este serviço.
req.method = 'GET';
req.query = req.body;
delete req.body;
}
Next();
}, {
find: function(params, callback) {
// faça alguma coisa
}
});

Algum de vocês poderia esclarecer se estou faltando alguma coisa aqui? Ou melhor ainda, deixe-me saber se há uma maneira melhor de fazer isso?

Isso pode ser feito com os novos métodos personalizados (https://github.com/feathersjs/feathers/issues/1976) vindos da v5

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

andysay picture andysay  ·  3Comentários

Mattchewone picture Mattchewone  ·  4Comentários

jordanbtucker picture jordanbtucker  ·  4Comentários

huytran0605 picture huytran0605  ·  3Comentários

corymsmith picture corymsmith  ·  4Comentários