Вызов bit.ly REST API из Apex

Sep 08 2020

Использование Bit.ly V4 API через этот код:

HttpRequest req2 = new HttpRequest();           
req2.setEndpoint('https://api-ssl.bitly.com/v4/shorten');           
req2.setMethod('POST');
req2.setHeader('Authorization', 'Bearer ...');
String jsonBody = '{"long_url":"https://test.com"}';
req2.setBody(jsonBody);
req2.setHeader('Content-Type', 'application/json');

Http http2 = new Http();
HttpResponse res2 = http2.send(req2);           
system.debug(res2);

дает следующий ответ:

CALLOUT_RESPONSE [24] | System.HttpResponse [Status = Not Acceptable, StatusCode = 406]

Такой же запрос работает в Postman. Почему не работает в Apex?

Ответы

2 identigral Sep 09 2020 at 00:42

Ваш фрагмент кода

Http http2 = new Http();
HttpResponse res2 = http2.send(req2);           
system.debug(res2);

отправляет ссылку ( res2) в журнал отладки. Когда это происходит, SF вызывает toString()метод по ссылке, и вы видите System.HttpResponse [Status = Not Acceptable, StatusCode = 406]результат. toStringдает вам имя класса и строку состояния + связанный код. Этой информации недостаточно, чтобы понять, что происходит.

Если вы отправляете тело ответа в журнал отладки в дополнение к такому статусу

system.debug(res2.getStatusCode() + ': ' + res2.getBody());

ты бы увидел

<timestamp> USER_DEBUG [12]|DEBUG|406: {"message":"INVALID_ACCEPT_HEADER"}

Это в значительной степени говорит вам, что не так - вам нужно включить Acceptзаголовок, чтобы указать, что ваш клиент может принимать JSON в качестве ответа. Это работает:

...
req2.setHeader('Accept', 'application/json');

Http http2 = new Http();
HttpResponse res2 = http2.send(req2);           
system.debug(res2.getStatusCode() + ': ' + res2.getBody());

В зависимости от конфигурации Postman может автоматически добавлять заголовки к запросу. Хотя казалось, что ваш запрос в Postman был таким же, как и в Apex, на самом деле это не так. При тестировании REST API лучше использовать клиент командной строки, например curl.