api-request-builder
Provides an API to construct a URI for the HTTP API endpoints in a declarative way. Useful for building request uri
for requests.
Install
Node.js
npm install --save @commercetools/api-request-builder
Browser
<script src="https://unpkg.com/@commercetools/api-request-builder/dist/commercetools-api-request-builder.umd.min.js"></script>
<script>
// global: CommercetoolsApiRequestBuilder
</script>
createRequestBuilder(options)
Creates a request builder that allows to declaratively build a HTTP API request URI for the commercetools platform.
Arguments
The options
argument must be an object with a projectKey
property, and optionally a customServices
property
options -> { projectKey, customServices }
projectKey
(String): A required string specifying the project key to use for the request. Even though this is required, the project key can be omitted from the URI by passing{withProjectKey: false}
to.build()
customServices
(Object): A map of custom services that are not provided by default. This might be useful to build a request for a different API with similar query parameters.
A service is created by defining its features
. Features give a service specific characteristics to correctly build URIs. For example, if a service can query a resource by ID you would include queryOne
. Available features types are:
query
: allows to use standard query capabilities (page
,perPage
,sort
,where
,whereOperator
)queryOne
: allows to query a single resource (byId
,byKey
,byCustomerId
,byCartId
)queryLocation
: allows to query resources by location (byCountry
,byCurrency
,byState
)queryExpand
: allows to use reference expansion (expand
)search
: allows to use search capabilities (text
,fuzzy
,fuzzyLevel
,facet
,markMatchingVariants
,filter
,filterByQuery
,filterByFacets
)projection
: allows to use projections capabilities (staged
,priceCurrency
,priceCountry
,priceCustomerGroup
,priceChannel
)suggest
: allows to use suggest capabilities (searchKeywords
)
import {
createRequestBuilder,
features,
} from '@commercetools/api-request-builder'
const options = {
projectKey: 'my-project',
customServices: {
users: {
type: 'users',
endpoint: '/users',
features: [features.query, features.queryOne],
},
},
}
const requestBuilder = createRequestBuilder(options)
Default Services
const requestBuilder = createRequestBuilder(options)
const uri = requestBuilder.productProjections.build()
// uri = "/project-key/product-projections"
Default services match the commercetools API using a camel-case convention.
Endpoints | Service | Features |
---|---|---|
/login | login | create |
/cart-discounts | cartDiscounts | create, update, del, query, queryOne, queryExpand |
/carts | carts | create, update, del, query, queryOne, queryExpand |
/categories | categories | create, update, del, query, queryOne, queryExpand |
/channels | channels | create, update, del, query, queryOne, queryExpand |
/customer-groups | customerGroups | create, update, del, query, queryOne, queryExpand |
/customers | customers | create, update, del, query, queryOne, queryExpand |
/customers/password | customersPassword | create |
/customers/password-token | customersPasswordToken | create, queryOne |
/customers/password/reset | customersPasswordReset | create |
/customers/email-token | customersEmailVerificationToken | create, queryOne |
/customers/email/confirm | customersEmailVerification | create |
/custom-objects | customObjects | create, update, del, query, queryOne |
/discount-codes | discountCodes | create, update, del, query, queryOne, queryExpand |
/extensions | extensions | create, update, del, query, queryOne, queryExpand |
/inventory | inventory | create, update, del, query, queryOne, queryExpand |
/messages | messages | query, queryOne, queryExpand |
/me/active-cart | myActiveCart | queryOne |
/me/carts | myCarts | create, update, del, query, queryOne, queryExpand |
/me/orders | myOrders | create, update, del, query, queryOne, queryExpand |
/orders | orders | create, update, del, query, queryOne, queryExpand |
/orders/edits | orderEdits | create, update, del, query, queryOne, queryExpand |
/orders/import | orderImport | create, query |
/payments | payments | create, update, del, query, queryOne, queryExpand |
/product-discounts | productDiscounts | create, update, del, query, queryOne, queryExpand |
/product-projections | productProjections | query, queryOne, queryExpand, projection |
/product-projections/search | productProjectionsSearch | search, queryOne, queryExpand, projection |
/product-projections/suggest | productProjectionsSuggest | search, suggest, queryOne, projection |
/products | products | create, update, del, query, queryOne, queryExpand |
/product-types | productTypes | create, update, del, query, queryOne, queryExpand |
/ | project | update, query |
/reviews | reviews | create, update, del, query, queryOne, queryExpand |
/shipping-methods | shippingMethods | create, update, del, query, queryOne, queryExpand, queryLocation |
/shopping-lists | shoppingLists | create, update, del, query, queryOne, queryExpand |
/states | states | create, update, del, query, queryOne, queryExpand |
/subscriptions | subscriptions | create, update, del, query, queryOne, queryExpand |
/tax-categories | taxCategories | create, update, del, query, queryOne, queryExpand |
/types | types | create, update, del, query, queryOne, queryExpand |
/zones | zones | create, update, del, query, queryOne, queryExpand |
Note that markMatchingVariants
is set by default to false
which turns off this feature on the API.
Staged
It is possible to add the staged
boolean option to the uri. This decides whether to query the current
or staged
projections, for example in Product Projections. (Defaults to false)
const service = createRequestBuilder(options)
const uri = service.productProjections.staged(true).build()
Version
It is also possible to append the version of a resource to the uri when making a request that requires this (for example a DELETE
request). This can be done by passing the required version to the .withVersion()
method.
const service = createRequestBuilder(options)
const uri = service.channels.withVersion(2).build()
QueryOne
It is also possible to query for just one resource. QueryOne consists of byId
, byKey
, byCustomerId
, byCartId
.
When retrieving a resource using it's own ID, use byId
or byKey
.
const requestBuilder = createRequestBuilder(options)
const uri = requestBuilder.carts.byId('cartId').build()
When retrieving a resource by a customer or cart reference use byCustomerId
or byCartId
.
const requestBuilder = createRequestBuilder(options)
const uri = requestBuilder.carts.byCustomerId('customerId').build()
dataErasure
You can also append the dataErasure
option to the uri when making a delete request if you want to make sure all related data is deleted. For example, regarding the GDPR, this means that all personal data related to the particular object, including invisible data, is erased. More info here
This can be done by using the .withFullDataErasure()
method.
const service = createRequestBuilder(options)
const deleteUri = service.payments
.byId(12345)
.withVersion(3)
.withFullDataErasure()
.build()
withTotal
You can also append the withTotal
option to the uri when making a query. More info here.
This can be done by using the .withTotal(false)
method.
const service = createRequestBuilder(options)
const getUri = service.orders.withTotal(false).build()
Usage example
import { createRequestBuilder } from '@commercetools/api-request-builder'
import { createClient } from '@commercetools/sdk-client'
const requestBuilder = createRequestBuilder({ projectKey: 'my-project-key' })
const client = createClient({
middlewares: [...],
})
const channelsUri = requestBuilder.channels
.where('key = "foo"')
.perPage(1)
.withVersion(3)
.build()
const channelsRequest = {
uri: channelsUri,
method: 'GET',
}
client.execute(channelsRequest)
.then(result => ...)
.catch(error => ...)
Declarative Usage
A declarative API exists as an alternative to the imperative API (shown in the example above).
// same imports and instantiation as above
const channelsUri = requestBuilder.channels
.parse({
where: ['key = "foo"'],
perPage: 1,
version: 3,
})
.build()
Type of Params
This declarative parse
API accepts an object of the following shape:
{
// query-expand
expand?: Array<string>;
// query-id
id?: ?string;
key?: ?string;
customerId?: ?string;
cartId?: ?string;
// query-location
country?: ?string;
currency?: ?string;
state?: ?string;
// query-page
sort: Array<{ by: string, direction: 'asc' | 'desc' }>;
page: ?number;
perPage: ?number;
// query-projection
staged?: boolean;
priceCurrency?: string;
priceCountry?: string;
priceCustomerGroup?: string;
priceChannel?: string;
// query-search
text?: ?{
language?: string;
value?: string;
};
fuzzy?: boolean;
fuzzyLevel?: number;
markMatchingVariants?: boolean;
facet?: Array<string>;
filter?: Array<string>;
filterByQuery?: Array<string>;
filterByFacets?: Array<string>;
// query-suggest
searchKeywords?: Array<{language: string; value: string;}>;
// query
where?: Array<string>;
whereOperator?: 'and' | 'or';
// version
version?: string;
// dataErasure
dataErasure?: string;
// params
orderNumber?: number;
}
Mixed usage
The imperative API can be mixed with the declarative one.
// these both lead to the same result
requestBuilder.channels.parse({ page: 5 }).perPage(10).build()
requestBuilder.channels.perPage(10).parse({ page: 5 }).build()