I’m very excited to announce the initial beta release of an official PHP Client Library for Nexmo’s API. It’s been quietly on packagist as an alpha for a few weeks, and it’s great to make the official announcement the week of php[tek] – a conference we’ve loved being a part of for the past few years. Now, you can skip the rest of this and just grab the library (well, require it with composer):
composer require nexmo/client
But you really shouldn’t skip the next part, because the rest of this is kind of important.
Why ‘Official’?
First, we need to say a big thank you to those that have contributed open source client libraries for the API in the past. I’m pretty sure there are more PHP client libraries out there than any other language, and that seems about right for PHP. That’s why I can’t list them here, I’m sure I’d miss some. Building an official client library is in no way a slight to those projects, and I hope it’s clear how much that work is appreciated.
Having an official library is about us owning the responsibility of making it easy to build applications that use Nexmo’s API. And it’s a way for us to become more engaged with developer communities. PHP isn’t the only language, we’re working on building or adopting official libraries in NodeJS, Ruby, Python, C#, and Java. This is a long time in coming, and it’s something we should have done earlier.
Beta Release
This is a first beta release of the library. I want to make it clear that this is not ‘beta’ tag that hangs on so many services for so long. This is a real beta. For this release there is only coverage for Nexmo’s SMS API and the Verification API. The other APIs will follow in the next few weeks. (Worth noting: because this is a reboot of a past unfinished – and unpublished – library there is some code related to other APIs, but it needs an update to match the new client library design.)
Releasing the beta with coverage for these two APIs allows us to test a few key things before we get too far. We’ve open sourced a client library spec defining how all the official client libraries should operate. As the main author of that spec, it made sense for me to take the first shot at implementing it and get early feedback on how well the spec works for you. Here are those key features this release previews.
PSR-7
The spec requires that the client library use an existing HTTP client (no need to reinvent the wheel). Preferably a client library that’s part of the language. Which, for PHP, doesn’t really exist. The spec also recommends that users should be able to define and configure the HTTP client if possible.
In light of that the PHP library uses PSR-7. PSR-7 defines a common interface for HTTP requests and responses. Internally PSR-7 compatible messages are used for all API requests, and a PSR-7 message is expected back from the HTTP client. That means you can access the library’s HTTP requests or responses and inspect them without any special knowledge of how things work internally.
Yet that’s only half the equation. We also need a PSR-7 compatible HTTP client. Guzzle 6 supports sending and returning PSR-7 compatible HTTP messages, but here’s where things become interesting. While PSR7 is a standard interface for defining HTTP messages, there is no standard interface for executing those messages. Guzzle 6 may work for us, but tying the library to its interface specifically means it’s not easily user replaceable.
HTTPlug provides an HTTP client interface based on PSR-7. It allows you to replace a specific client library dependency with a dependency on any HTTPlug compatible adapter. However shipping a client library without an HTTP client adds a bit of friction during installation, so at this stage we’ve made the Guzzle 6 adapter a requirement. That means installation is the one line command you’d expect:
composer require nexmo/client
You can certainly require a different HTTPlug adapter to use the HTTP client of your choice. But since the Guzzle adapter is a requirement of the client library, you’ll have unused code in your vendor directory. If the need for a different HTTP client stems from a dependency conflict – say another package requires an earlier version of Guzzle – there’s no easy fix at this point.
Removing the Guzzle adapter from our library’s require would solve that. But it would also make installation look like this (where the first line could be replaced with any other adapter):
composer require php-http/guzzle6-adapter
composer require nexmo/client
Double the work, but it’s still only two lines. I’d love to know what you think about all this.
Webhooks
PSR-7 also supports server requests, a HTTP request made to your server instead of from your server. That’s perfect for the webhooks Nexmo’s API makes for things like an inbound SMS or a phonecall to your account.
Using server request, the client library provides an easy way to parse, verify, and use the data sent in those webhooks.
1 |
$inbound = \Nexmo\Message\InboundMessage::createFromGlobals(); |
Our goal is to make it as simple as possible for you to work with webhooks. Of course, you can also construct InboundMessage
with a PSR-7 ServerRequest you created if you need customization.
Entities
Like many client libraries that are simple wrappers around an HTTP client, you can pass the client an array of values that match the API’s expected parameters. Here’s how you’d request a number be verified (sent a confirmation code, and later confirmed) using the Verify API:
$verification = $client->verify()->start([
‘number’ => ‘14845551212’,
‘brand’ => ‘My App’
]);
And you can treat the response as an array:
echo “Started verification with an id of: ” . $verification[‘request_id’];
But you can also use much richer entities (the term I’m using in the spec) that represent API concepts and objects, just like the objects created from inbound webhooks. Instead of just passing the parameters expected by the Verify API, you can create a verification object, and then use the client to ‘start’ it:
$verification = new \Nexmo\Verify\Verification(‘14845551212’, ‘My App’);
$client->verify()->start($verification);
echo “Started verification with an id of: ” . $verification->getRequestId();
This allows client side validation of required parameters. And the entities are easy to use if your editor or IDE supports code completion. Here’s how you could set a few optional parameters before sending an SMS:
$text = new \Nexmo\Message\Text(‘14845551212’, ‘16105553950’, ‘Test message using PHP client library’);
$text->setClientRef(‘test-message’)
->setClass(\Nexmo\Message\Text::CLASS_FLASH);
The entities are designed to be extended (or even replaced) by your own custom objects if needed. That could allow you to persist them directly in some database, or add additional logic of your own.
If you use simple arrays with the library, you’re really just using the entity’s support for array access. So you’re free to switch between the two as needed. Keep in mind that the entity normalizes names as well as returned data. Using array access is a proxy of the raw data, the names and values, from the API’s response.
echo “Sent message to ” . $text[‘to’] . “. Balance is now ” . $text->getRemainingBalance();
Errors and Exceptions
You may have noticed that none of the examples test if the API call actually worked. That’s because an exception is thrown for any failed API request. A few specific exception classes are used to identify the general type of error. The entity that caused the problem is injected into the exception, allowing you to inspect that or even the underlying HTTP request and response.
$text = new \Nexmo\Message\Text(‘14845551212’, ‘16105553950’, ‘Test message using PHP client library’);
try {
$client->message()->send($text);
} catch (\Nexmo\Client\Exception\Request $e) {
//PSR-7 Response Message
$response = $e->getEntity()->getResponse();
}
Roadmap
While the current beta only covers a few of Nexmo’s APIs, it covers all of those concepts and we really want to know what you think about them. Open an issue on the spec repository if you have thoughts on the overall roadmap for all client libraries, or create an issue on the nexmo-php project with language specific questions.
And play with it! If you need a place to start, I’ll be publishing a simple tutorial on building a group SMS chat using all the features just mentioned later this week. Keep an eye on this blog Friday.
This is just the start, and we want you to be a part of this process.
php[tek]
Are you at php[tek] this week? Swing by our booth, say hi, and let me know what you think about the client library. If you’re not at php[tek] (really? why not?), you can catch the keynotes on the livestream. If you missed this morning’s keynote, you can replay it too. And follow us (@nexmo and @tjlytle) on Twitter to make sure you don’t miss some spontaneous live streams of the evening festivities.