[SalesForce] System.HttpResponse[Status=Unauthorized, StatusCode=401] from Apex Controller

I have the following code, that retrieves picklist values dependent on a record type:

public static List<String> getPicklistValuesByRecordType(String objectType, String recordTypeId, String fieldName) {
    //Endpoint
    system.debug('objectType : ' + objectType);
    system.debug('recordTypeId : ' + recordTypeId);
    system.debug('fieldName : ' + fieldName);
    String endpoint = URL.getSalesforceBaseUrl().toExternalForm();
    endpoint += '/services/data/v41.0';
    endpoint += '/ui-api/object-info/{0}/picklist-values/{1}/{2}';
    endpoint = String.format(endpoint, new String[]{ objectType, recordTypeId, fieldName });
    EncodingUtil.urlEncode(endpoint,'UTF-8');

    //HTTP Request send
    HttpRequest req = new HttpRequest();
    req.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId()); 
    req.setEndpoint(endpoint);
    req.setMethod('GET');

    system.debug('endpoint: ' + endpoint);
    Http http = new Http();
    HTTPResponse res = http.send(req);
    system.debug('res: ' + res);
    //Parse response
    List<String> result = new List<String>();
    Map<String,Object> root = (Map<String,Object>) JSON.deserializeUntyped(res.getBody());
    if(!root.containsKey('values')){ 
        return result; 
    }
    List<Object> pValues = (List<Object>)root.get('values');
    for(Object pValue : pValues){
        Map<String,Object> pValueMap = (Map<String,Object>)pValue;
        result.add((String)pValueMap.get('value'));

    }
    System.debug(result);
    return result;
}

When i run the following code from Execute Anonymous Window, i receive

System.HttpResponse[Status=OK, StatusCode=200]

But when running it from apex code that's being called by a component, i receive

System.HttpResponse[Status=Unauthorized, StatusCode=401]

Maybe its because i can't get UserInfo.getSessionId() from the code?

Please advise.

Best Answer

Which API version is your code saved under? Direct access to SF's API from Apex was improved in Winter '19 (v44). If your code is older, that might explain why it doesn't work. Also, their example code used Bearer instead of OAuth in the Authorization header:

Http h = new Http();
HttpRequest req = new HttpRequest();  
req.setEndpoint(Url.getOrgDomainUrl().toExternalForm()
   + '/services/data/v44.0/limits');
req.setMethod('GET');
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
HttpResponse res = h.send(req);

See https://releasenotes.docs.salesforce.com/en-us/winter19/release-notes/rn_apex_streamline_api_calls.htm