Search code examples
node.jsrestrouterputkoa

Howto Koa Router PUT done right


[Because koa-router maintainer wishes to ask on stackoverflow I opened an account]

Edit: It is about the NPM you get by 'npm install koa-router'

How to use Koa-Router and PUT the right way with sending data to the server ?

I would do it like this:

// trivial stuff ommitted
router.put('/devices/myDevice',  (ctx, next) => {
    console.log('ctx:',ctx);
    ctx.body = "nothing in ctx which looks like my data: whatever"
    next();
});

And the client side:

fetch('http://localhost:3000/devices/myDevice',{
            method: 'PUT',
            data: "whatever"
        })
        .then(function(data){
            return data.json();
        }).then(function(res){
        })
        .catch(function(err) {
            console.log('Fetching myDevice Error:', err);
          });

Doing this, my ctx looks like this:

ctx: { request:
{ method: 'PUT',
 url: '/devices/myDevice',
 header:
  { host: 'localhost:3000',
    connection: 'keep-alive',
    'content-length': '0',
    origin: 'null',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
     AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 
     Safari/537.36',
    accept: '*/*',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7' } },
    response:
    { status: 404,
    message: 'Not Found',
    header: { vary: 'Origin', 'access-control-allow-origin': 'null' } },
     app: { subdomainOffset: 2, proxy: false, env: 'development' },
    originalUrl: '/devices/myDevice',
    req: '<original node req>',
    res: '<original node res>',
     socket: '<original node socket>' }

As one can see I get a 404 but the route is triggered to console.log(ctx)... I also cannot see the data which I try to send to the server. Cors Headers are set btw. Other Routes like GET and DELETE work fine.

Is this a bug or is anyone out there could reproduce the described behaviour ?


Solution

  • As you mentioned, this was an issue with your fetch. It takes in a body property (not data) in the options.

    Example usage:

    fetch('http://localhost:3000/devices/myDevice', {
      method: 'PUT',
      body: JSON.stringify({ name: 'john', age: 30 })
    })
      .then(function(data) {
        return data.json();
      })
      .then(function(res) {})
      .catch(function(err) {
        console.log('Fetching myDevice Error:', err);
      });
    

    Fetch Docs: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch