Is Sync Gateway somehow incompatible (in PUT method) with node request library?

I tried to use node request lib to communicate with SG Admin API.
request.get calls work like a charm, but when it comes to PUT requests SG response status is 400 (Bad request).

I doublechecked the same request.put call against mocked express PUT endpoint - it works, I can see parsed json body.
Is there anything special to consider using request.put with SG?
My request code is:

> let path = syncURL + docID;  // http://localhost:4985/gw/guestlist_event_ca8ed753-7ab7-4052-8c49-fe3ba38de66c
    request({
      uri: path,
      method: 'PUT',
      json: JSON.stringify(doc),
      timeout: 1000,
      body: JSON.stringify(doc)
      },
      (error, response, body)=> {
        if (error) {
.... other stuff
   }

Built-in node’s http.request PUT method (with same parameters) works with SG with no issues, so I have workaround and it’s just matter of wondering - why SG doesn’t accept request.put calls?
Something tiny missed?

What error do you see ?

As I wrote - statusCode 400, Bad request.

Sorry missed the error code. Can you console.log the request that is going out including headers? Also may be worthwhile to turn on logging on SGW to see what it dislikes about the request.
I can’t think of a reason why the request made via http.request should be handled any differently than the one via request module (assuming its the same ).

That’s the thing - I also have no idea what’s difference.
In SG logs I found this:

PUT /gw/guestlist_event_ca8ed753-7ab7-4052-8c49-fe3ba38de66c (ADMIN)
2018-03-08T13:12:23.662+03:00 WARNING: Couldn’t parse JSON in HTTP request: json: cannot unmarshal string into Go value of type db.Body – db.ReadJSONFromMIME() at attachment.go:215
2018-03-08T13:12:23.663+03:00 HTTP: #312: --> 400 Bad JSON (1.0 ms)

But as you can see I use the same JSON.stringify(doc) statement as in http.request to prepare body…
Is there any way to see what SG recieves in body?

I reproduced your problem to check it. You don’t want to stringify the JS object. Also, I believe the json option is supposed to be true/false. (They go as a pair, so just supply the JS object and set json: true). So the call should look like

request({
  uri: "http://localhost:4985/gw/guestlist_event_ca8ed753-7ab7-4052-8c49-fe3ba38de66c",
  method: 'PUT',
  json: true,
  timeout: 1000,
  body: doc
  },
  (error, response, body)=> {
    console.log(error, response, body);
  }
);
1 Like

Thank you very much, it works without stringify.
Strange that request docs don’t say anything abouth already incorporated stringify if you set json: true…

BTW, you can just set json to body, so like this it will work as well:

1 Like