REST Service to Expose Attachments as Public CURL

My use case behind this blog post is to expose Salesforce Attachment (Image/Pdf/Video) as a public accessible CURL, without having to authenticate to Salesforce. And we are going to use REST Web-services and Public Sites to do this!


Step 1: Create an Apex REST class with below code snippet.

/*
* Purpose : Apex rest webservice to return attachment body for a given id
* 
* Developer: SFDC_Dev
* 
*/

@RestResource(urlMapping='/Document_V1/*')
global class DocumentV1 {
    @HttpGet
    global static void docBody() {        
        RestRequest request = RestContext.request;
        RestResponse res = RestContext.response;
        try {
            // Retrieve attachment id from the request url
            String docId = request.requestURI.substring(request.requestURI.lastIndexOf('/')+1);
            // Query attachment sObject to get the specific attachment using attachment id        
            Attachment a = [Select Id, Name, Body From Attachment Where Id=:docId]; 
            // Assing proper image extension base on file type
            if (a.Name.containsIgnoreCase('.jpeg') || a.Name.containsIgnoreCase('.jpg'))
                res.addHeader('Content-Type','image/jpg');
            if (a.Name.containsIgnoreCase('.png'))
                res.addHeader('Content-Type','image/png');
            if (a.Name.containsIgnoreCase('.gif'))
                res.addHeader('Content-Type','image/gif');
            if (a.Name.containsIgnoreCase('.pdf'))
                res.addHeader('Content-Type', 'application/pdf');
            if (a.Name.containsIgnoreCase('.mp4'))
                res.addHeader('Content-Type', 'video/mp4');
            // Assign attachment body to the response body
            res.responseBody = a.Body;            
        } catch(exception e) {
            res.responseBody = Blob.valueOf(e.getMessage()); 
        }
    }
}

Step 2: Create Public Site with below settings and also make sure to enable access for the above class on this specific Site Profile using "Public Access Settings".

Now go ahead and attach few attachments like image/pdf/gif on Account object and have those attachment id's handy for testing. Below I am going to test with those Id's using Workbench/CURL and also from the browser to see the responses!

Results from Workbench Testing:


Results from CURL Testing:



Now when I use above Curl's to open them in any browser, It should let me view the actual Attachment!

Sample Gif in a browser:



Sample Pdf in a browser:



Few Pros and Cons to consider before implement above:
  • As we are using Public Sites to expose the Attachments, so there is always a security issue tied to this. However we are returning attachment using its Id, but its always a best practice to white list all the IP address (From which the request may come) by adding them to 'Login IP Ranges' for the Public Site Profile. By doing this no one can access the url from outside those IP's.
  • With Public Site's there is a Daily Limit for the usage and this varies based on License Type, so keep an eye on those limits.
  • Attachments comes under File storage part of the storage limits which should not be an issue on data storage limits, but its always a best practice to purge all unwanted attachments.
  • Notes and Attachments do not support in Lightning and all the Attachments go under "Files", however legacy attachments can still be viewed in Lightning so please be aware of this. We will have to use "ContentVersion" sObject to implement similar functionality for Lightning.


  • Thank you

    Comments

    Popular posts from this blog

    Displaying Toast Message from Modal in Lightning Components

    Lightning RecordForm - An enhanced Lightning Data Service

    Lightning Component to display dynamic sObject data