Nowadays there are hundreds of cryptocurrencies and we live in a speculative boom of them. If you are in this business, you may want to stay up to date with the information of any cryptocurrency using the free CoinMarketAPI.
How does the API works?
The CoinMarketAPI exposes 3 endpoints. In this case we are going only to use one the /ticker
endpoint to retrieve the information about a single Cryptocurrency. This API returns the information of a Cryptocurrency from its id in JSON format:
https://api.coinmarketcap.com/v1/ticker/<Currency ID>/
The API allows you to convert the currencies to the most known currencies in the world with the following identifiers: "AUD", "BRL", "CAD", "CHF", "CNY", "EUR", "GBP", "HKD", "IDR", "INR", "JPY", "KRW", "MXN", "RUB":
https://api.coinmarketcap.com/v1/ticker/<Currency ID>/?convert=EUR
Although the API is totally free, the authors impose a limit that you may want to apply when requesting this information:
- Please limit requests to no more than 10 per minute (see step 3).
The endpoints of the API update every 5 minutes.
Important
In this article we'll explain you how to request the information of a currency with a plain Guzzle http client and a cached one as it should be.
1. Install GuzzleHttpClient
Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services. It has a really simple interface for building query strings, POST requests, streaming large uploads, streaming large downloads, using HTTP cookies, uploading JSON data and so on.
To make a request to the API via PHP, you will need this library. You can install it using the following composer command:
composer require require guzzlehttp/guzzle
Alternatively modify the composer.json
file and add the dependency manually:
{
"require": {
"guzzlehttp/guzzle": "^6.3",
},
}
And finally install them using composer install
. For more information about this library, please visit the official repository at Github here.
2. Request information about a Cryptocurrency
The main point of the tutorial is about how to retrieve information about a cryptocurrency as Bitcoin, Ethereum, Litecoin etc. Using the Guzzle client you will make a request in the same way you do with a browser.
The first you need to do is to create Guzzle Client instance. The client has a method namely request, that expects as first argument the type of request and as second argument the URL of the request that you want to make. In this case the first argument will be the GET
format and as second argument you will use the URL of the CoinMarketCap API (with the ID of the cryptocurrency you want and optionally the currency conversion). Once the request finishes, you can retrieve the response body by using the getBody method of the result that in this case will be a plain string in JSON format, so be sure to convert it into an array using json_decode
. The generated array will contain all the information that the API provides about the currency:
Warning
Do not use the following code in production, it's just to show you how the Guzzle Client can be used to access the API. The requests aren't being cached !
Use this only in local environment (development environment) to test the library for first time.
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
// Important: Include the GuzzleClient
use GuzzleHttp\Client;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction()
{
// Retrieve information about the bitcoin currency
$bitcoinInfo = $this->getCryptoCurrencyInformation("bitcoin");
// About the Ethereum currency but in Euros instead of United States Dollar
$ethereumInfo = $this->getCryptoCurrencyInformation("ethereum", "EUR");
// And so on with more than 1010 cryptocurrencies ...
// Send the information of the currencies to a Twig view
return $this->render("default/index.html.twig", [
"bitcoin" => $bitcoinInfo,
"ethereum" => $ethereumInfo
]);
}
/**
* Retrieves the complete information providen by the coinmarketcap API from a single currency.
* By default returns only the value in USD.
*
* WARNING: do not use this code in production, it's just to explain how the API works and how
* can the information be retrieved. See step 3 for final implementation.
*
* @param string $currencyId Identifier of the currency
* @param string $convertCurrency
* @see https://coinmarketcap.com/api/
* @return mixed
*/
private function getCryptoCurrencyInformation($currencyId, $convertCurrency = "USD"){
// Create a new Guzzle Plain Client
$client = new Client();
// Define the Request URL of the API with the providen parameters
$requestURL = "https://api.coinmarketcap.com/v1/ticker/$currencyId/?convert=$convertCurrency";
// Execute the request
$singleCurrencyRequest = $client->request('GET', $requestURL);
// Obtain the body into an array format.
$body = json_decode($singleCurrencyRequest->getBody() , true)[0];
// If there were some error on the request, throw the exception
if(array_key_exists("error" , $body)){
throw $this->createNotFoundException(sprintf('Currency Information Request Error: $s', $body["error"]));
}
// Returns the array with information about the desired currency
return $body;
}
}
At this point you can request information about the 2 desired currencies namely Bitcoin and Ethereum. As you can see in our index action we are returning a Twig file that contains the following code:
{# default/index.html.twig #}
{% extends "base.html.twig" %}
{% block body -%}
Price of the Bitcoin (USD): <b>$ {{ bitcoin.price_usd }}</b> <br>
Price of the Ethereum (EUR): <b>€ {{ ethereum.price_eur }}</b> <br>
{# Dump the entire arrays into the view #}
{{dump(bitcoin)}}
{{dump(ethereum)}}
{% endblock %}
So if you access the index route of the controller, Twig will output the following HTML content:
However, this won't last longer. If you keep requesting without a Cache, the API of CoinMarketCap will warn you that you are making too many requests, so you will need to implement a Cache Manager for the requests.
3. Implement some cache system
You will need to implement a cache manager for the Guzzle Client, because as mentioned before, the API is totally free and we can't abuse of it (besides you will get an exception due to the many requests that you may make if you don't implement a cache "429 Too Many Requests").
The Cache Manager needs to be implemented by you in the way you want. For the lazy developers that may don't know how to handle any cache, we will show an example using a Filesystem Cache. For this, you will need to install 2 extra libraries to handle the Cache, we are talking about the Cache Component of Symfony and the Guzzle Cache Middleware. Install the libraries using composer by running the following commands:
REM Install the Cache Component of Symfony:
composer require symfony/cache
REM And install the Cache Middleware for Guzzle:
composer require kevinrob/guzzle-cache-middleware
After the installation you will be able to use their classes in your own controller. By using the Cached Client of Guzzle that we are going to implement using the filesystem instead of a plain client, a new folder will appear in the cache directory of your symfony project (in this case /var/cache/GuzzleFileCache
). Don't forget to give properly the permissions to write into the folder.
The example creates a new method namely getGuzzleFileCachedClient
. This method should be private and returns a new instance of a Guzzle Client (used to request the information about a currency) however with a Cache Implementation using the Symfony Cache Component and the Guzzle Cache Middleware. You are free to implement a service from the client to keep your controller clean, but if you are only testing, making it in the controller can be easier and faster. As mentioned by the API the perfect cache time will be of 10 minutes (600 seconds). The rest of the code in the controller will stay the same but instead of creating a new client, use the cached one:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
// Important: add the required classes
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use Kevinrob\GuzzleCache\CacheMiddleware;
use Kevinrob\GuzzleCache\Storage\Psr6CacheStorage;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
use Kevinrob\GuzzleCache\Strategy\GreedyCacheStrategy;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction()
{
// Retrieve information about the bitcoin currency
$bitcoinInfo = $this->getCryptoCurrencyInformation("bitcoin");
// About the Ethereum currency but in Euros instead of United States Dollar
$ethereumInfo = $this->getCryptoCurrencyInformation("ethereum", "EUR");
// And so on with more than 1010 cryptocurrencies ...
// Send the information of the currencies to a Twig view
return $this->render("default/index.html.twig", [
"bitcoin" => $bitcoinInfo,
"ethereum" => $ethereumInfo
]);
}
/**
* Retrieves the complete information providen by the coinmarketcap API from a single currency.
* By default returns only the value in USD.
*
*
* @param string $currencyId Identifier of the currency
* @param string $convertCurrency
* @see https://coinmarketcap.com/api/
* @return mixed
*/
private function getCryptoCurrencyInformation($currencyId, $convertCurrency = "USD"){
// Create a Custom Cached Guzzle Client
$client = $this->getGuzzleFileCachedClient();
// Define the Request URL of the API with the providen parameters
$requestURL = "https://api.coinmarketcap.com/v1/ticker/$currencyId/?convert=$convertCurrency";
// Execute the request
$singleCurrencyRequest = $client->request('GET', $requestURL);
// Obtain the body into an array format.
$body = json_decode($singleCurrencyRequest->getBody() , true)[0];
// If there were some error on the request, throw the exception
if(array_key_exists("error" , $body)){
throw $this->createNotFoundException(sprintf('Currency Information Request Error: $s', $body["error"]));
}
// Returns the array with information about the desired currency
return $body;
}
/**
* Returns a GuzzleClient that uses a cache manager, so you will use the API without any problem and
* request many times as you want.
*
* The cache last 10 minutes as recommended in the API.
*/
private function getGuzzleFileCachedClient(){
// Create a HandlerStack
$stack = HandlerStack::create();
// 10 minutes to keep the cache
$TTL = 600;
// Retrieve the cache folder path of your Symfony Project
$cacheFolderPath = $this->get('kernel')->getRootDir() . '/../var/cache';
// Instantiate the cache storage: a PSR-6 file system cache with
// a default lifetime of 10 minutes (60 seconds).
$cache_storage = new Psr6CacheStorage(
new FilesystemAdapter(
// Create Folder GuzzleFileCache inside the providen cache folder path
'GuzzleFileCache',
$TTL,
$cacheFolderPath
)
);
// Add Cache Method
$stack->push(
new CacheMiddleware(
new GreedyCacheStrategy(
$cache_storage,
600 // the TTL in seconds
)
),
'greedy-cache'
);
// Initialize the client with the handler option and return it
return new Client(['handler' => $stack]);
}
}
Remember that you have access with this API to the value of the (till the date of this article) 1010 Crypto currencies in the market, so don't forget to take a look to the homepage of CoinMarketCap here.
Happy coding !