Introduction
The Galaxy API aims to provide application developers with all necessary tools, services and information required to produce custom applications based on the rich functionality exposed by the Galaxy platform.
As such, the API was designed to:
- Expose Galaxy’s functionality in a concise, understandable way
- Be discoverable
- Be specific, without ambiguity
- Follow current technology standards
Api Structure
The underlying Galaxy platform is in essense a container for what we will be reffering to as “Business Domains”.
A Business Domain is a collection of code and configuration artifacts, working together to provide:
- Invoke-able Services and Business Operations
- A Database Schema and the corresponding Data Transfer Objects and CRUD operations
- Pre-Defined custom Queries, invoke-able by name that also allow filtering & paging
- Miscellaneus data to complement the business functionality in the form of Lookups and Enumerations
The API steps in to provide all this functionality as a tree, where services, data entities, views, lookups and enumerations are child URLs of a domain, which is itself a child of the API root.
For example, if we consider the case where we have a domain called Glx, which contains an invokable service called IdentityDocuments, which itself exposes a business operation called VerifyIdentityDocument, the URI for invoking the operation would be:
/api/glx/services/identitydocuments/verifyidentitydocument
In it’s generic form, the URI above translates to:
/api/{DomainName}/services/{ServiceName}/{OperationName}
This generic pattern is present throughout the API, where in essence we drill-down into the contents of a business domain to discover useful data and functionality.
Being Discoverable
Typically, a Galaxy installation will contain at least two business domains, and hundreds of data entities and services. It was really important during the initial design of the API that the developer has some way of discovering all those objects and their functionality.
Thus, at each “parent” node in the API tree, we provide links to specific contents.
For instance, the URI /api
will return a list of all contained business domains:
[
{
"Uri": "/api/glx",
"Name": "Glx"
},
{
"Uri": "/api/crm",
"Name": "Crm"
},
{
"Uri": "/api/plx",
"Name": "Plx"
}
]
If we were to drill-down a little further and inspect the Glx domain at /api/glx/
:
{
"Uri": "/api/glx",
"Entities": "/api/glx/entities",
"Services": "/api/glx/services",
"Views": "/api/glx/views",
"Enums": "/api/glx/enums",
"Lookups": "/api/glx/lookups",
"Name": "Glx"
}
As you can see, the Glx domain exposes quite a few areas of functionality, again represented by child URIs of our “parent”, the Glx domain URI.
Drilling further on down the Glx tree by following the provided links will take us to a list of objects for each area of functionality. Those lists typically resemble the /api
response.
For /api/glx/entities
:
[
{
"Domain": "glx",
"Name": "AcquaintSource",
"Uri": "/api/glx/entities/acquaintsource"
},
{
"Domain": "glx",
"Name": "AddressType",
"Uri": "/api/glx/entities/addresstype"
},
{
"Domain": "glx",
"Name": "AdvProdSettings",
"Uri": "/api/glx/entities/advprodsettings"
},
{
"Domain": "glx",
"Name": "AdvProdSettingsCmp",
"Uri": "/api/glx/entities/advprodsettingscmp"
},
{
"Domain": "glx",
"Name": "AllocationSheetAL",
"Uri": "/api/glx/entities/allocationsheetal"
}
]
Following /api/glx/services
, /api/glx/enums
or /api/glx/lookups
would produce a similar list of available objects. The pattern is applied in the same manner for all sublinks of the Glx domain.
Being Concise, Specific
Appart from being repetitive and intuitive to follow, the “tree” URI convention also prevents name clashes for objects in different domains that happen to expose the same name. Identifying the parent domain and object type in the URI will always produce unique URIs, since there can never be two business domains with the same name.
However, discover-ability alone will not inform the developer of what our objects look like, or what operations they might expose. So, to make the API as specific and consise as possible, it will provide metadata at each leaf node in the tree.
Suppose we wanted to find out what operations are exposed by a given service in the Glx domain. Let’s examine the DataTalkObjects service - a service that allows us to import and export data from/to Galaxy.
The URI for DataTalkObjects is /api/glx/services/datatalkobjects
:
[
{
"Arguments": {
"Parameters": [
{
"Type": "string, null",
"IsArray": true,
"Name": "tableNames",
"Required": true,
"DefaultValue": null
}
]
},
"Name": "DeleteMappingTables",
"Uri": "/api/glx/services/datatalkobjects/deletemappingtables"
}
]
Note: Please note that this example is a partial payload. In actual reality the DataTalkObjects exposes a significant number of operations.
The response we got from the server actually lists the Operations exposed by the service, providing useful metadata for each one.
Throughout use of the API, this will become a familiar pattern, since most types of objects, including Services, Views and Data Entities expose such detailed metadata to consumers of the API.
Technology Standards
The Galaxy API is organized around REST. Our API has predictable, resource-oriented URLs, and uses HTTP response codes to indicate API errors. We use built-in HTTP features, like HTTP authentication and HTTP verbs, which are understood by off-the-shelf HTTP clients.