30

I need to make a PATCH http request.

I made the rather incredible discovery today that I can't set an HttpRequest to use the PATCH method, as when sending the request I get a callout exception:

System.CalloutException "Invalid HTTP method: PATCH"

The work around I've found on Stack Exchange and elsewhere is only applicable to a Salesforce Rest API request:

PATCH request using Apex HttpRequest

This is therefore not helpful to me as I'm calling out to a third party.

By what manner of magic can I send a PATCH request from Salesforce?

The only work around I can think of is to not do it from Apex - this is not an option.

1

3 Answers 3

28

Post-Winter 21

As Daniel Ballinger mentioned in his new Answer below - Winter 21 will bring support for this at last! See https://releasenotes.docs.salesforce.com/en-us/winter21/release-notes/rn_apex_callouts_patch.htm


Pre-Winter 21

Update to this answer, there are 2 workarounds to the missing PATCH verb in HttpRequest that may work in a few specific contexts:

  1. If you are calling TO Salesforce, FROM Salesforce (e.g. an integration between two orgs), you can append ?_HttpMethod=PATCH to the endpoint. Note that this is not a feature of the HttpRequest object, it doesn't do anything clever with this - rather this is a workaround that Salesforce has in place to allow callers to its REST APIs to do PATCH calls when the caller doesn't otherwise allow the PATCH verb (which ironically is a problem Salesforce itself suffers). That is to say, this will not help you if you're calling to a non-Salesforce system. See https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_update_fields.htm:

If you use an HTTP library that doesn't allow overriding or setting an arbitrary HTTP method name, you can send a POST request and provide an override to the HTTP method via the query string parameter _HttpMethod. In the PATCH example, you can replace the PostMethod line with one that doesn't use override:
PostMethod m = new PostMethod(url + "?_HttpMethod=PATCH");

  1. As noted by @zachelrath in their answer on this question (https://salesforce.stackexchange.com/a/77833/2429), setting the header X-HTTP-Method-Override is an option, e.g.
    req.setMethod('POST');
    req.setHeader('X-HTTP-Method-Override','PATCH');
    However, this is a convention that some servers follow in order to support libraries that don't support certain HTTP verbs, rather than a guarantee of success. This DOES NOT work when calling into Salesforce, Salesforce ignores this header.

If neither of the above options work, it appears to not be possible using Apex alone, without some kind of middleware (e.g. Heroku proxy to turn certain POSTs into PATCHes, or [horror of horrors] a dummy visualforce page to run an XHR) - which you've indicated is not an option.

The reason for this looks like it might be because Salesforce behind the scenes is using JDK's HttpURLConnection, which restricts the http verbs you can use to the HTTP/1.1 defaults. This bug report for your issue in a JDK/HttpUrlConnection context I found is marked as "Won't Fix" in OpenJDK - https://bugs.openjdk.java.net/browse/JDK-7016595. Note the description and error message match your issue.

This other StackExchange question indicates it's a problem across JDKs 6,7, and 8 (and I would presume earlier): https://stackoverflow.com/questions/17780693/ - same error phrasing still: Invalid HTTP method: PATCH

16

I had this same experience recently when trying to do a callout to the Google Calendar API, and apparently there's a common practice of servers listening for an X-HTTP-Method-Override header where you pass in the desired HTTP method to use, but then set the request method to POST:

req.setHeader('X-HTTP-Method-Override','PATCH');
req.setMethod('POST');

For context, here's a more full example:

String eventId = 'abcdefghijklmnop';
String user = '[email protected]';
user = EncodingUtil.urlEncode(user, 'UTF-8');

Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint(
   'https://www.googleapis.com/calendar/v3/calendars/'+user+'/events/'+eventId
);
req.setBody('{ "Description" : "test description }');
req.setHeader('Authorization', 'Bearer ' + authToken);
req.setHeader('Content-Type', 'application/json');
req.setHeader('X-HTTP-Method-Override','PATCH');
req.setMethod('POST');
HttpResponse res = h.send(req);
0
2

The release notes for Winter `21 (v50.0) indicate that PATCH support will be coming to Apex.

Update Resources with the PATCH HTTP Method in Apex Callouts

To make partial or full updates to a resource in an HTTP web service, specify the PATCH method in the HttpRequest class. Previously, only the PUT method was supported for full updates.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .