3 Tips for using the Sugar Metadata API

What is the Sugar Metadata API?

As you probably know, Sugar metadata encompasses the settings, data model (Vardefs), and visual layouts (Viewdefs) used by the Sugar application. The majority of changes made to Sugar using Sugar Studio, Module Builder, or even custom code are implemented by modifying metadata.

How can I know that the custom field or custom modules that you need for your integration to work exists in Sugar?

How can I know what are the allowed values are valid for a Sugar dropdown field?

How can I know if a field is required?

How can I know the display label for a given field?

How can I know what fields are available in Sugar that I can map back to an external data source?

The answers to all these questions and many more can be found in Sugar metadata.

On the server side, metadata is implemented as an extensible set of PHP associative arrays. But how does this information get sent out to Sugar clients like your web browser, mobile app, or even the Outlook plug-in? This is accomplished via the Sugar metadata endpoint of the Sugar REST API.

GET /rest/v11/metadata HTTP/1.1
Host: localhost:8080
OAuth-Token: ...
Content-Type: application/json

The full metadata response comes back as a very large JSON object. It's usually a few megabytes in size (about 3MB in a stock version of Sugar Winter '18) but can be much larger depending on customizations. Make sure compression is enabled on your web server if you are going to be using it over a slow connection!

The value to using the Metadata API is that you can discover changes in Sugar configuration and Sugar customizations. New custom fields, relationships, modules, changes to Sugar views and layouts, and much more are all represented in Sugar metadata responses.

From a REST API perspective, the only way to accurately know the current data model for any given Sugar instance is to use the Metadata API.

Since the Metadata API is so important, here are three important tips to keep in mind to make development easier.

Tip 1: Retrieve only what you need

Metadata API calls can generate a huge response depending on your Sugar instance configuration and the customizations that may exist. You should specify filters on your metadata request in order to narrow the response to the data that you actually need. Narrowing what is returned will improve performance on both server side in terms of generating the response but also on the client side where you need to parse the JSON response.

For example, if you are integrating with only the Accounts module then you may only need to concern yourself with that part of the metadata. Specify a type_filter and module_filter as URL parameters to only return module metadata for the Accounts module. Other supported type_filter options are server_info, config, relationships, labels, languages, currencies, views, layouts, full_module_list, and etc.

GET /rest/v11/metadata?type_filter=modules&module_filter=Accounts HTTP/1.1
Host: localhost:8080
OAuth-Token: ...
Content-Type: application/json

Tip 2: Cache metadata, update only when it changes

You can safely cache the metadata that you need if you keep track of the _hash value returned in the metadata response.

You should present that hash value in the X-Metadata-Hash header on subsequent Sugar REST API requests to ANY endpoint. If the metadata hash is out of date then Sugar will return a 412 PRECONDITION FAILED HTTP response. You should then retrieve updated metadata from the Metadata API and store the updated metadata hash value.

GET /sugar/rest/v11/Accounts HTTP/1.1
Host: localhost:8080
OAuth-Token: ...
Content-Type: application/json
X-Metadata-Hash: 705fb99230e2ec60b59f481c6831a7cf

Also worth mentioning, many of our API resources (such as records and our metadata) implement HTTP caching. If an API response contains an E-Tag HTTP header then you can safely cache the response body as well as the E-Tag value. If you present this value in the If-None-Match HTTP header properly on a subsequent HTTP GET request for that resource, you will get an empty 304 NOT MODIFIED response back if it is safe to continue using the cached version of the previous response. This is another approach to reduce needless processing.

GET /rest/v11/metadata?type_filter=modules&module_filter=Accounts HTTP/1.1
Host: localhost:8080
OAuth-Token: ...
Content-Type: application/json
If-None-Match: 705fb99230e2ec60b59f481c6831a7cf

This allows you to update your local copy of the metadata as soon as it changes and precisely no more often than that.

Tip 3: Different users and platforms will retrieve different responses

If a user is assigned a role that doesn't have access to a particular module then the metadata for that module will not be returned when that user accesses the metadata API. Makes sense, right? 

Sugar also support things like role based views which will provide alternative UI layout metadata based upon the current user's role.

Different platforms will have different metadata responses as well. The mobile platform retrieves module metadata that reflects the needs of our Sugar Mobile app. Mobile UI components look a lot different from what you see when you access Sugar from your browser. The metadata that is retrieved is significantly different to accommodate these changes.

For example, the mobile client uses separate edit and detail views for representing records instead of a single record view like you find in Sugar web client. This is represented in the mobile metadata response.

  • Yes, your custom View metadata is included in metadata API responses. In fact, that's a debug step for me to check when I'm trying to create a new View and it isn't showing up for some reason.

    Changes to Vardefs and Viewdefs should all be included automatically by the standard metadata management implementation. There shouldn't be a reason to hook into MetadataManager class directly to get your metadata to appear and, in fact, I wouldn't recommend overriding or modifying MetadataManager at all.

    We like to say that Sugar is "metadata aware". We automatically combine metadata that appears under the custom/ directory with the out of the box metadata defined elsewhere when computing a Metadata API response. In fact, that's the typical scenario for metadata to change.

    For example, somebody creates a custom field in Studio which generates new metadata under custom/ directory, Sugar recalculates a metadata hash value which differs from what is found in Sugar clients, Sugar clients then pull down the updated metadata that includes this new custom field via the metadata API.

  • Nice article Matt!

    Just a couple quick questions I was wondering after reading:

    • Would this work for custom views? In other words, if I created the file custom/modules/Accounts/clients/base/views/myview/myview.php, would the API return that as well, if I specified it?
    • Would it need to be structured in a certain way in order for the object to be identified by the API? If so, would I need to hook it into the MetadataManager class or something similar?

    Thanks!

    Richard

  • Hello Matt,

    nice and useful article. Thank you so much for sharing with us.

    Thanks
    Prashant