Apex Framework / library for consuming REST services

The ffhttp library should do the trick: https://github.com/financialforcedev/ffhttp-core

It includes error handling, redirections, building header fields, oauth, mime attachments and more.

EDIT - Sample code

Say you want to consume the JSONPlaceholder /users rest resource. You could create a Named Credential for the URL.

JSONPlaceholder named credential

Then you can use ffhttp to make the request, handle the failure or successful response and deserialize into the intended format. FFHTTP only includes an OAuth client but it's pretty simple to create your own...

public with sharing class ffhttpSample {

    * DTO for remote object result
    private class RemoteUser {
        Integer id;
        String name;
        String username;
        String email;

    * Vanilla HTTP request
    public static RemoteUser[] getUsers() {
        Http http = new Http();

        HttpRequest request = new HttpRequest();

        HttpResponse response = http.send(request);        
        if (response.getStatusCode() == 200) {
            return (RemoteUser[])JSON.deserialize(response.getBody(), List<RemoteUser>.class);
        } else {
            return new RemoteUser[]{};

    * FFHTTP request
    public static RemoteUser[] getUsersFfhttp() {
        SimpleClient client = new SimpleClient();
        client.setCredentials(new ffhttp_Client.NamedCredentials('JSONPlaceholder'));

        SimpleClientRequest request = new SimpleClientRequest(
            new ffhttp_JsonDeserializer(List<RemoteUser>.class));

        // Execute and parse the response.
        // Alternatively you can use executeUnparsed() to return the response body as a String
        return (RemoteUser[])request.execute();

    * FFHTTP client implementations
    private class SimpleClient extends ffhttp_Client.AbstractClient {}
    private class SimpleClientRequest extends ffhttp_Client.AbstractClientRequest {
        SimpleClientRequest(IAbstractClient client, String endpoint, String requestMethod, ffhttp_IDeserialize deserializer) {
            super(client, endpoint, requestMethod, null, deserializer);