JavaScript Client for Account Management APIs
AM Client provides TypeScript interfaces and functions for interaction with Elastic Path hypermedia RESTful APIs. It aims to enable all functionality offered by EP Studio through strongly-typed interfaces and functions.
Functions and interfaces in this library are generated using Elastic Path hypermedia XML definition files.
Examples for the features are:
- Strongly-typed async functions for performing all CRUD operations
- Functions for submitting all available forms
- Zoom query creation with autocompletion
- Full TypeScript support
Installing the Library
To install the library run:
npm install @elasticpath/am
Using JavaScript Client
import * as am from '@elasticpath/am';
const client = am.createClient({ serverBaseUrl: 'http://yourserver' });
client.account('account123')
.fetch({
statusinfo: {},
subaccounts: {
element: {}
}
})
.then(accountRes => {
const name = accountRes.name;
const legalName = accountRes.legalName;
const subaccounts = accountRes.subaccounts.elements;
});
Creating a Client Object
Call the am.createClient(options)
function and provide a ClientOptions
object as in the following example:
interface ClientOptions {
serverBaseUrl: string;
selectedLocale: string | (() => string);
authHeader: string | (() => string);
onAuthError: (err: Error) => void;
queryParams: { [key: string]: string | null | undefined };
}
ClientOptions Properties
Property | Required | Type | Description |
---|
serverBase | Required | string | Base URL of the backend server |
selectedLocale | Optional | string or () => string | Locale used to set x-ep-user-traits header when making a request. If this function is set, for every request, the client calls this function. |
authHeader | Optional | string or () => string | Auth token used to set Authorization header when making a request. If this function is set, for every request, the client calls this function. |
onAuthError | Optional | (Error) => void | If this function is set, the client calls this function when server returns status 401. Use this callback function to provide authorization logic, for example redirect user to a login page. |
queryParams | Optional | `{ [key: string]: string | null |
Fetching a Resource
Client object provides a function for every resource that can be located using resource URI.
To load a resource, you need to identify it using the appropriate client function and then call .fetch()
method on the result and provide a zoom query object to load.
fetch()
method returns a Promise
that can be await
-ed:
const response = await client.account(accountUri).fetch({ statusinfo: {} });
Response object consists of:
- A
uri
property that can be used for subsequent fetch
operations - Data fields of the current resource
- Requested relationship properties to other resources
Zoom object is serialized into a zoom query that is used as the ?zoom=
parameter in the request.
Every node in zoom object (with or without children) will be a new entry in the zoom query.
For example a zoom object:
.fetch({
a: {
b: {},
c: {
d: {}
}
}
});
will result with a following zoom query:
a,a:b,a:c,a:c:d
Root
The root resource is considered the main entry point which is used to discover other resources.
const myProfileRes = await client.root().fetch({
myprofile: {
primaryemail: {}
}
});
Typically root
is used to get a list of other resources and their respective uri
s after which a uri
can be used to zoom further into a particular object details.
const rootRes = await client.root().fetch({
accounts: {
element: {}
}
});
const accountUri = rootRes.account.element[0].uri;
const accountRes = await client.account(accountUri).fetch({
statusinfo: {},
selfsignupinfo: {}
});
Updating Resources
Update the responses for entity type resource by calling an update(newValues)
method as in the following example:
await client.account(accountUri).update({
name: 'new name',
legalName: 'new legal name',
externalId: 'new ext id',
registrationId: 'new reg id'
});
Deleting Resources
To delete a recurse Run the delete()
method as in the following example:
await client.account(accountUri).delete();
Even though the update()
and delete()
methods change the state of the resources on the server, previously fetched responses remain unchanged.
To render the latest information on the screen, some of the resources might need to be reloaded from the server.
Forms
When a zoom object contains a relationship to a form, the response object contains function to submit the form.
A form submission returns resources that can be zoomed, so you must add a .fetch()
function to a form function to actually submit a form.
This is because a form submission returns resources that can be zoomed.
const rootRes = await client.root().fetch({
searches: {
accountsearchform: {}
}
});
const accountsRes = await rootRes.searches.accountsearchform({
keywords: 'search query',
page: 1,
pageSize: 10
})
.fetch({
element: {
statusinfo: {}
}
});
Responses that might include a long list of resources are being paginated.
Response for a paginated resource contains a pagination
object is in addition to the elements array.
The pagination object contains information about the current page as well as previous()
and next()
methods that fetches previous and next page respectively.
const rootRes = await client.root().fetch({
accounts: {
element: {}
}
});
const accountsPage = rootRes.accounts;
accountsPage.elements
accountsPage.pagination
const nextPage = await accountsPage.next();
nextPage.elements;
nextPage.pagination;
const prevPage = await nextPage.previous();
pagination
property contains information about the current page as well as the total number of elements.
This can be useful when rendering page info and page number links.
pagination = {
current,
pages,
pageSize,
results,
resultsOnPage
}
Selectors
Selectors provide a list of predefined options that a user can select from.
Single-select Selector
This selector provides two values as options. You can select only one option.
This selector might be a checkbox or a dropdown menu with two options.
In a response object, the selected option is represented with chosen
property and the other options with choice
property.
Both options have a select()
method associated with them.
Following in an example:
const accountRes = await client.account(accountUri).fetch({
statusinfo: {
selector: {
chosen: {},
choice: {}
}
}
});
await accountRes.statusinfo.selector.choice.select();
Multi-select Selector
This selector provides list of values where every one can be selected or unselected (including all of them or none).
This selector can be a list of checkboxes on UI.
Response for this kind of selectors will have chosen
and choice
as an arrays containing objects with the select()
methods as in the following example:
const roleInfoRes = await client.roleInfo('uri').fetch({
selector: {
chosen: {},
choice: {}
}
})
await roleInfoRes.selector.choice[0].select();
Similar to calling update()
and delete()
methods, calling select()
will change the resource on the server but will not change the state of the response object.
You may need to reload some of the resources in order to get up to date response object.