an introduction to the analytics api in apex -...
TRANSCRIPT
![Page 1: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/1.jpg)
An Introduction to the Analytics API in Apex
Peter Knolle - peterknolle.com Salesforce.com Solutions Architect – Trifecta Technologies
![Page 2: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/2.jpg)
What will be covered
� History / Background
� Example uses
� Running a report
� Accessing report metadata
� Filtering
� Unit testing
� Debugging / Exploring the API
![Page 3: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/3.jpg)
History
� Salesforce had excellent reporting capabilities, but…
� …did not have an “official/supported” way to access the reports through code.
� Screen scraping – Ick!
� iframe – Yuck!
![Page 4: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/4.jpg)
Analytics API Releases
� Winter ‘14 – REST-based API released � Requires Oauth session � JSON requests/ responses
� Spring ‘14 – Apex-based API released � Same functionality as REST-based API, but in Apex
![Page 5: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/5.jpg)
What can we do with it?
� Easily use with charting libraries such as d3, Google Charts, etc.
![Page 6: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/6.jpg)
What can we do with it?
� Dynamic filtering
![Page 7: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/7.jpg)
What can we do with it?
� Reduce maintenance: no need to create parallel SOQL to get report data.
� Dynamic Dashboards
� It is very new, so much much more to come…
![Page 8: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/8.jpg)
API
� REST and Apex APIs have same functionality � Run reports (synchronous and asynchronous) � Get report metadata � Get report result data � Dynamic filtering � Get list of recent asynchronous report runs
� Classes are in the Reports namespace, e.g., Reports.ReportManager, Reports.ReportMetadata, etc.
![Page 9: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/9.jpg)
Running a Report
� Set of four overloaded methods for both synchronous and asynchronous
� Synchronously Reports.ReportResults res = Reports.ReportManager.runReport(reportId);
� Asynchronously Reports.ReportInstance instance = Reports.ReportManager.runAsyncReport(reportId);
// later…
Reports.ReportResults res = instance.getReportResults();
![Page 10: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/10.jpg)
Overloaded runReport / runAsyncReport methods
� runReport(reportId) – Includes summary level information but will not include details (i.e., rows).
� runReport(reportId, includeDetails) – Includes the details, too.
� runReport(reportId, metadata) – Applies additional filters specified in the Reports.ReportMetadata metadata argument
� runReport(reportId, metadata, includeDetails) – Includes the details, too.
![Page 11: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/11.jpg)
More on Asynchronous
Reports.ReportInstance instance = Reports.ReportManager.runAsyncReport(reportId);
instId = instance.getId();
//some other method…
Reports.ReportInstance inst = Reports.ReportManager.getInstance(instId);
String status = inst.getStatus();
if (status != 'Running’ && status != 'New’) {
reportResults = inst.getReportResults();
}
![Page 12: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/12.jpg)
ReportResults
“Contains the results of running a report.”
� getFactMap() – Returns summary-level data or summary and detailed data for each row or column grouping. Detailed data is available if the includeDetails parameter is set to true when the report is run.
![Page 13: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/13.jpg)
Fact Map Keys
Report format Fact map key pattern
Tabular T!T: The grand total of a report. Both record data values and the grand total are represented by this key.
Summary <First level row grouping_second level row grouping_third level row grouping>!T: T refers to the row grand total.
Matrix <First level row grouping_second level row grouping>!<First level column grouping_second level column grouping>.
![Page 14: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/14.jpg)
Report with two grouping levels
![Page 15: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/15.jpg)
Using ReportResults – Aggregates
Map<String,ReportFact> fm = results.getFactMap();
Reports.ReportFact fact = fm.get(‘T!T’);
Decimal grandTotal = (Decimal) fact.getAggregates().get(0).getValue();
Decimal rowCount = (Decimal) fact.getAggregates().get(1).getValue();
![Page 16: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/16.jpg)
Using ReportResults - Details
Reports.ReportResults results = Reports.ReportManager.runReport(REPORT_ID, true);
![Page 17: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/17.jpg)
Using ReportResults - Details
Reports.ReportFactWithDetails detailFact = (Reports.ReportFactWithDetails)results.getFactMap().get('0_0!T');
List<Reports.ReportDetailRow> allRows = detailFact.getRows();
Decimal cellValue = (Decimal) rows.get(0).getDataCells().get(0).getValue();
System.assert(cellValue == 114048);
![Page 18: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/18.jpg)
Want more on the fact map?
� See Decode the Fact Map section in Apex Developer’s Guide:http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_analytics_fact_map.htm
![Page 19: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/19.jpg)
Metadata
Three types of metadata
� Report Metadata � Reports.ReportMetadata
� Report Extended Metadata � Reports.ReportExtendedMedtadata
� Report Type Metadata � Reports.ReportTypeMetadata
![Page 20: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/20.jpg)
ReportMetadata
“Report metadata gives information about the report as a whole, such as the report type, format, summary fields, row or column groupings, and filters that are saved to the report.“
� Simple attributes - getId(), getName(), getDeveloperName(), getReportFormat(), getReportType()
� Complex collections - getReportFilters(), getDetailColumns(), getAggregates(), getGroupingsDown/Across()
![Page 21: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/21.jpg)
Accessing ReportMetadata
Reports.ReportDescribeResult descRes = Reports.ReportManager.describeReport(reportId);
ReportMetadata md = descRes.getReportMetadata(),
OR the ReportMetadata from a specific run
ReportMetadata md = reportResults.getReportMetadata();
// Example Uses
Id reportId = md.getId();
List<String> colApiNames = md.getDetailColumns();
![Page 22: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/22.jpg)
ReportExtendedMetadata
“Report extended metadata provides additional, detailed metadata about summary and grouping fields, including data type and label information.”
� getAggregateColumnInfo() – API name, label, data type of aggregations (row count, sum, etc.)
� getDetailColumnInfo() – API name, label, data type of columns
� getGroupingColumnInfo() – API name, label, data type, grouping level of each grouping in the ReportMetadata’s groupingsDown/Across.
![Page 23: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/23.jpg)
Accessing ReportExtendedMetadata
Reports.ReportDescribeResult descRes = Reports.ReportManager.describeReport(reportId);
Reports.ReportExtendedMetadata md = descRes.getReportExtendedMetadata(),
OR the ReportExtendedMetadata for a specific run
Reports.ReportExtendedMetadata emd = reportResults.getReportExtendedMetadata();
![Page 24: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/24.jpg)
Accessing ReportExtendedMetadata
Integer level = emd.getGroupingColumnInfo()
.get(‘STAGE_NAME’)
.getGroupingLevel();
System.assert(0 == level);
![Page 25: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/25.jpg)
ReportTypeMetadata
“Contains report type metadata, which gives you information about the fields that are available in each section of the report type, plus filter information for those fields.”
� List<Reports.ReportTypeColumnCategory> getCategories()– returns a list of categories, which in turn contain their list of fields with information about the fields
![Page 26: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/26.jpg)
Accessing ReportTypeMetadata
Reports.ReportDescribeResult descRes = Reports.ReportManager.describeReport(reportId);
Reports.ReportTypeMetadata tmd = descRes.getReportTypeMetadata(),
// Not part of Reports.ReportResults
![Page 27: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/27.jpg)
Accessing ReportTypeMetadata
Reports.ReportTypeColumnCategory category = tmd.getCategories().get(0);
String oppInfoLabel = category.getLabel();
Boolean isFilterable = category
.getColumns().get(‘AMOUNT’)
.getFilterable();
![Page 28: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/28.jpg)
Filtering
� Columns must be filterable.
� Must use only allowed filter operators per data type – ReportManager. getDatatypeFilterOperatorMap()
� Can override existing filter by getting and setting value
� Can add additional filters
� Use Reports.ReportMetadata run/AsyncReport versions, e.g., � runReport(reportId, reportMetadata)
![Page 29: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/29.jpg)
Adding a filter
Reports.ReportFilter fromFilter = new Reports.ReportFilter();
fromFilter.setColumn('CLOSE_DATE');
fromFilter.setOperator('greaterOrEqual');
fromFilter.setValue('2014-01-01');
Reports.ReportDescribeResult dr = Reports.ReportManager.describeReport(REPT_ID)
Reports.ReportMetadata md = dr.getReportMetadata();
md.getReportFilters().add(fromFilter);
Reports.ReportResults results = Reports.ReportManager.runReport(REPT_ID, md, true);
![Page 30: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/30.jpg)
Unit Testing
� Report runs always ignore SeeAllData annotation, and always include org data
� Use a filter to limit testing to data created in the unit test
Opportunity opp = TestUtil.generateOpp(‘ApexUnitTest’);
List<Reports.ReportFilter> filters = getTestFilter(opp.Name);
reportMetadata.setReportFilters(filters);
![Page 31: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/31.jpg)
Exploring / Debugging
� Useful to see entire object
� Helpful to determine API names
� Debug logs and Developer Console aren’t really designed for viewing that information
![Page 32: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/32.jpg)
Debugging - JSON
Output to <pre> tag JSON.serailizePretty(results);
public String debugRes{ get; set; }
// somewhere in a method
Reports.ReportResults results = Reports.ReportManager.runReport(REPORT_ID);
debugRes = JSON.serializePretty(results);
<apex:outputPanel id="debug">
<pre>{!debugRes}</pre>
</apex:outputPanel>
![Page 33: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/33.jpg)
Debugging View State
![Page 34: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/34.jpg)
Debugging REST Explorer
![Page 35: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/35.jpg)
Selected Limitations
� 500 synchronous report runs / hour
� 20 synchronous report run requests at a time
� 1,200 asynchronous requests / hour
� 200 requests at a time for async instances
� Returns up to the first 2,000 report rows
� Apex: Asynchronous not allowed in Batch
� Apex: Report runs in unit tests include org data
![Page 36: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/36.jpg)
What was covered
� Apex API new in Spring ’14
� Some examples
� Methods to run reports, filter, get results, get metadata
� Unit testing
� Debugging / Exploring
![Page 37: An Introduction to the Analytics API in Apex - Meetupfiles.meetup.com/12723112/PeterKnolle_2014_APR_03_LVSFDCDUG.pdf · An Introduction to the Analytics API in Apex Peter Knolle](https://reader034.vdocuments.site/reader034/viewer/2022042708/5ae3d7427f8b9a595d8ef810/html5/thumbnails/37.jpg)
More
� Apex Developer’s Guide - http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_analytics_intro.htm
� Articles by Product Manager, Analytics @ Salesforce: https://medium.com/@arun_sfdc
� Articles on my blog – http://peterknolle.com/posts
� Spring ‘14 right around the corner or get a pre-release org in the meantime