Note: for the immediate future, the suite of packages described here are still in alpha. They will change, will be refined, so expect things to break. Please feel free to try them out, get involved, raise issues and PRs (even if it is just to fill gaps in the documentation).
Note: this package supports the Xero OAuth 1.0a API API only.
It is derived from a fork of the oauth1
branch of https://github.com/XeroAPI/Xero-OpenAPI
with some back-ports of some fixes from the oauth2
and master
branches.
This package will be replaced with an OAuth 2.0 version.
This package is generated from the Xero OpenAPI descriptions and provides:
- Support for the Accounting, Fixed Assets, Bank Feeds and Files APIs.
- Models for all schemas in the OpenAPI description.
- A PSR-18 client decorator for senting requests and constructing response objects.
The root namespace is Consilience\Xero
with extended namespaces for each API:
- Consilience\Xero\AccountingSdk\
- Consilience\Xero\BankfeedsSdk\
- Consilience\Xero\AssetsSdk\
- Consilience\Xero\FilesSdk\
This package needs a PSR-18 to send and receive requests. It also requires a PSR-17 HTTP factory for construcing request messages.
For Partner applications, a PSR-18 client with automatic token refresh can be found
here: consilience/xero-api-client.
There is a Laravel/Lumen wrapper for this client here:
consilience/laravel-xero-api-client.
For Private and Public applications, you will need to create your own PSR-18
client,
or extend the consilience/xero-api-client
and perhaps provide a PR.
The examples below assume you have a PSR-18
client named $psr18client
with access to your
Xero application of whatever type.
The Xero OpenAPI Description gives each operation a name.
These operations each have a method created.
For example, the Account API has an operation getAccounts
.
This gives us the method:
public function getAccounts($ifModifiedSince = null, $where = null, $order = null)
{
...
}
which can be found in Consilience\Xero\AccountingSdk\Api\AccountingApi (warning: it's a big class). It takes three parameters, all optional, and some further details are given below. First let's create the API object to call this operation.
use Consilience\Xero\AccountingSdk\Configuration as accountingConfiguration;
use Consilience\Xero\AccountingSdk\Api\AccountingApi;
// You can pass in the PSR-17 factories, or leave them out for auto-discovery.
$accountingConfiguration = new accountingConfiguration([
'syncClient' => $psr18client,
'uriFactory' => // your PSR-17 URI factory
'requestFactory' => // your PSR-17 request factory
'streamFactory' => // your PSR-17 stream factory
]);
$accountingApi = new AccountingApi($accountingConfiguration);
Given that, you can request a list of Accounts:
$accounts = $accountingApi->getAccounts();
That will return a Consilience\Xero\AccountingSdk\Model\Accounts
model,
containing a list of zero or more Consilience\Xero\AccountingSdk\Model\Account
models.
If there is an error in the response, then Consilience\Xero\AccountingSdk\ApiException
will be thrown.
This exception will give access to the parsed payload (if there is one, which this endpoint
does not provide), the PSR-7
request, and the PSR-7
response:
use Consilience\Xero\AccountingSdk\ApiException;
try {
$accounts = $accountingApi->getAccounts();
} catch (ApiException $e) {
// Original PSR-7 request.
$e->getRequest();
// PSR-7 response.
$e->getResponse();
// Parsed payload or null if none.
$e->getResponseObject();
}
Some Xero APIs will provide an error moel payload, with details of the error,
which may include individual validation messages for parameters that fail validation.
Sometimes it's just a 404
with no meaningful payload.
This operation takes three parameters:
/**
* Operation getAccounts
*
* Allows you to retrieve the full chart of accounts
*
* @param \DateTime $ifModifiedSince Only records created or modified since this timestamp will be returned (optional)
* @param string $where Filter by an any element (optional)
* @param string $order Order by an any element (optional)
*
* @throws \Consilience\Xero\AccountingSdk\ApiException on non-2xx response
* @throws InvalidArgumentException
* @return \Consilience\Xero\AccountingSdk\Model\Accounts
*/
The $ifModifiedSince
parameter is straightforward.
It takes a PHP DateTime
object,
or any string that strtotime() can parse,
and goes to milli-second resolution.
The $where
and $order
parameters are a little more structured, but still srings.
Details for setting up a where
filter can be found here:
https://developer.xero.com/documentation/api/requests-and-responses#get-explicit
You do not need to escape any of the where-parameter - just create the string and pass it in. Examples:
// All accounts modified since 2016, that are still active, have the word "test"
// in their name, then order by last updated time, then (uselessly) the currency
// code descending.
$accounts = $accountingApi->getAccounts(
'2016-01-01',
'Status=="ACTIVE" && name.contains("test"),
'updatedDateUTC asc, currencyCode desc'
);
Any errors in these parameters will result in an exception.
The API description for this operation does not specify any payload, so none is parsed.
However, the raw response $e->getResponse()
is available to inspect.
This is a PSR-7
response, so the payload, status code and body is available.
Other APIs and operations have a well-defined error response payload, and that will be parsed.
If you want to run an operation without handling exceptions, append "WithHttpInfo" to the end of the action:
$accounts = $accountingApi->getAccountsWithHttpInfo();
// Returns an array:
// {
// 'model' => // The parsed payload
// 'request' => // The PSR-7 request
// 'response' => // The PSR-7 response
// }
There are a number of places you may need to create models in relation to the API:
- When passing a parameter to an operation that expects a model.
- When parsing a
PSR-7
ServerRequest
to a model, for inbound requests (running as a server).
TODO...from PSR-7 ServerRequest or Response, from array, or built by hand from data or nested models.
The code is generated using the consilience/openapi-generator-psr18
package
at present. The steps to do this from a bash shell are:
-
From the root directory of this package, install the root dependencies (
consilience/openapi-generator-psr18
andXeroAPI/Xero-OpenAPI
):composer install
-
Run the bash script:
bin/generate.sh
That's it. generate.sh
will run the generator against the custom templates
for each of the Xero API descriptions, with the code going into the apis
directory.
- The file streaming generation functionality has not been worked on. Multipart streams also need to be taken into account, which may require access to a new factory to construct.
- The generation of asynchrnous requests are disabled at present.
- Request and response schema objects are not immutable. I would like to implmenent that, but work needs to be done learning how to customise the generataor code (Java) and developing the custmisation as an extension or plugin.
- Each API is generated with its own set of configuration and serialisation classes. Using an interface, it should be possible to use just one, shared between the APIs.
- Creation of some general helper methods for construction where-conditions and perhaps date-based queries.