1

I've been developing a web client to interact with a REST API server, and would like to use PATCH method.

Although I've tried to write a request body into PATCH's request, I found the body remains empty. PUT or POST works fine in the same way though.

I can use PUT instead, but does anyone know if my usage of http module is wrong?

Thank you in advance.

var http = require('http');

module.exports = {

  patch: function(path, data, done, fail){
    var jsonData = JSON.stringify(data);
    var options = {
      headers: {
        'Content-Type':'application/json;charset=UTF-8',
        'Content-Length':jsonData.length,
      }
    };
    var req = this.request(path, "PATCH", done, fail, options);

    // THIS CODE DOESN'T WRITE jsonData INTO REQUEST BODY
    req.write(jsonData);
    req.end();
  },

  request: function(path, method, done = () => {}, fail = () => {}, options = { headers: {} } ){
    options.path = path;
    options.method = method;
    return http.request(options, function(res){
      var body = '';
      res.setEncoding('utf8');
      res.on("data", function(chunk){
        body += chunk;
      });
      res.on("end", function(){
        // process after receiving data from server
      });
    }).on("error", function(e) {
      // process after receiving error
    });
  }
}

2 Answers 2

1

I ended up using the "request" library for node.js. Following code works:

var request = require("request");
(...)

function patch(path, entity){
    var deferred = q.defer();     
    var escapedPath = escapeSpaces(path);
    AuthProvider.retrieveToken().done(function (authToken){
        var headers ={
            'OData-MaxVersion': '4.0',
            'OData-Version': '4.0',
            'Content-Type': 'application/json; charset=utf-8',
            'Authorization': 'Bearer '+ authToken,
            'Accept': 'application/json'     
        }

        var options = {
            url: "https://"+resourceApiId+"/api/data/v8.0/"+escapedPath,
            method: 'PATCH',
            headers: {
                'OData-MaxVersion': '4.0',
                "OData-Version": '4.0',
                "Content-Type": "application/json; charset=utf-8",
                "Authorization": 'Bearer '+ authToken,
                "Accept": "application/json"                
            },
            json: entity      
        };  

        request(options, function(error, response, body){
                if (!error) {
                    console.log("patchrequest statuscode: "+response.statusCode )
                    deferred.resolve(true);
                }
                deferred.reject(error);
            }
        );
    });

    return deferred.promise;
}
Sign up to request clarification or add additional context in comments.

Comments

1

I have the very same problem with this code:

function patch(path, entity){
    var deferred = q.defer();     
    var escapedPath = escapeSpaces(path);
    var stringEntity = JSON.stringify(entity);
    AuthProvider.retrieveToken().done(function (authToken){
        var options = {
            host: resourceApiId,
            path: "/api/data/v8.0/"+escapedPath,
            method: 'PATCH',
            headers: {
                'OData-MaxVersion': '4.0',
                "OData-Version": '4.0',
                "Content-Type": "application/json; charset=utf-8",
                "Authorization": 'Bearer '+ authToken,
                "Accept": "application/json"
            }       
        };  

        var reqToCrm = https.request(options, function(resFromCrm){
            var body = '';
            resFromCrm.on('data', function(d) {
                body += d;
            });
            resFromCrm.on('end', function() {
                try{
                    var parsed = JSON.parse(body);
                    if(parsed.error){
                        var errorString = "webApiRequest.js/patch: An error returned from CRM: " + parsed.error.message + "\n"
                        +"Body Returned from CRM: " + body;
                        console.log(errorString);
                        deferred.reject(errorString);
                    }
                    deferred.resolve(parsed);
                }
                catch (error){
                    var errorString = "Error parsing the response JSON from CRM.\n"
                    +"Parse Error: " + error.message + "\n"
                    +"Response received: "+ body;
                    console.log(errorString);
                    deferred.reject(errorString);
                }

            });            
        });

        reqToCrm.on('error', function(error) {
            console.log(error.message);
            deferred.reject("webApiRequest.js/post: Error returned on 'PATCH' against CRM \n" + error.message);
        });

        reqToCrm.write(stringEntity);
        reqToCrm.end(); 
    });

    return deferred.promise;
}

I Also already tried making a POST request and setting 'X-HTTP-Method-Override': 'PATCH. Did not work either. I can not use any other Request method as Dynamics CRM forbids it.

1 Comment

Me either, I ended up using POST instead. Thank you for sharing your experience!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.