By hozza
Hi all,
I’ve having some trouble understanding the API, in the past with other API’s I’ve just used a simple PHP with curl script to action a specific task on a service. I don’t need a full library and the Digital Ocean has more dependencies than I care to count…
For some reason the DO API is not working with a simple script like this while others do, I must be missing something?
function basic_api_handle($key, $method, $URI, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer '.$key,
'Content-Type: application/json')
);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_URL, $URI);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$result = curl_exec($ch);
if($result === false) error_log("API ERROR: Connection failure: $URI", 0);
curl_close($ch);
return json_decode($result, true);
}
var_dump(basic_api_handle($api_key, 'POST', 'https://api.digitalocean.com/v2/domains', array('name' => 'my-domain.tld', 'ip_address' => '1.2.3.4')));
This results in** “unprocessable_entity” **and “Name can’t be blank” - it suggests to me the data is not being sent correctly? although, as far as I can tell, it is…
I’ve also posted this on Stack Overflow but it may be to specific (Digital Ocean) to get any decent answers. I have setup a bounty for a solution too :) http://stackoverflow.com/questions/43619504/how-do-i-make-a-simple-php-api-handler/43854037
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Accepted Answer
A very simple way to do this, without curl
would be using file_get_contents
and streams.
<?php
function doapi( $key, $method, $uri, array $data = [] )
{
/**
* DigitalOcean API URI
*/
$api = 'https://api.digitalocean.com/v2';
/**
* Merge DigitalOcean API URI and Endpoint URI
*
* i.e if $uri is set to 'domains', then $api ends up as
* $api = 'https://api.digitalocean.com/v2/domains'
*/
$uri = $api . DIRECTORY_SEPARATOR . $uri;
/**
* Define Authorization and Content-Type Header.
*/
$headers = "Authorization: Bearer $key \r\n" .
"Content-Type: application/json";
/**
* If $data array is not empty, assume we're passing data, so we'll encode
* it and pass it to 'content'. If $data is empty, assume we're not passing
* data, so we won't sent 'content'.
*/
if ( ! empty( $data ) )
{
$data = [
'http' => [
'method' => strtoupper( $method ),
'header' => $headers,
'content' => json_encode( $data )
]
];
}
else
{
$data = [
'http' => [
'method' => strtoupper( $method ),
'header' => $headers
]
];
}
/**
* Create Stream Context
* http://php.net/manual/en/function.stream-context-create.php
*/
$context = stream_context_create( $data );
/**
* Send Request and Store to $response.
*/
$response = file_get_contents( $uri, false, $context );
/**
* Return as decoded JSON (i.e. an array)
*/
return json_decode( $response, true );
}
/**
* Example Usage
*/
var_dump(doapi(
'do-api-key',
'get',
'domains'
));
An example is at the bottom of the file.
var_dump(doapi(
'do-api-key',
'get',
'domains'
));
Which just dumps the output of the response. You could assign it to a variable, like so:
$response = doapi( 'do-api-key', 'get', 'domains' );
You could then filter through the response as needed. The above is very basic and doesn’t have any sort of error handling built-in, so you’d need to make sure you’re passing exactly what is required.
Looking at the initial function definition:
function doapi( $key, $method, $uri, array $data = [] )
You’ll pass:
$key
= DigitalOcean API Key
$method
= Upper or Lowercase Method (get, post, delete, etc). It’ll be converted to uppercase.
$uri
= The endpoint your calling, without a /
(i.e. domains, droplets, etc).
$data
= An array of data that isn’t JSON encoded (the function will encode it for you).
…
For $uri
, you could pass endpoints with a slash between them, i.e. domains/action
(where action is an endpoint off domains`), though no front or trailing slash should be added.
…
I just tested this locally using one of my API keys and it works. Hopefully that’ll help :-).
No problem at all, happy to help :-). I’ve not been on SO in a while – I probably need to get back on there at some point.
As a side note, if you want to tinker with cURL too, here’s a modified version of the original function from my first post. It only handles GET and POST requests as-is, but you can extend the function to handle PUT, DELETE, etc as needed.
<?php
function doapi( $key, $method, $uri, array $data = [] )
{
$api = 'https://api.digitalocean.com/v2';
$uri = $api . DIRECTORY_SEPARATOR . $uri;
$method = strtoupper( $method );
$headers = [
"Authorization: Bearer $key",
"Content-Type: application/json"
];
$ch = curl_init();
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_URL, $uri );
if ( $method === 'POST' && ! empty( $data ) )
{
curl_setopt( $ch, CURLOPT_POST, 1 );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $data ) );
}
$result = curl_exec( $ch );
$result = json_decode( $result, true );
curl_close( $ch );
return $result;
}
$result = doapi(
'do-api-key',
'post',
'droplets',
[
'name' => 'example.com',
'region' => 'nyc3',
'size' => '512mb',
'image' => 'ubuntu-16-04-x64'
]
);
var_dump( $result );
The only difference is the code. You’d use it the same as you do the other function. Hopefully that’ll help you either way – using whichever method you prefer to use :-).
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.