Even more batteries included: Platform.sh configuration librariesCrellWed, 03/06/2019 - 16:23
Blog
Libraries? We've got libraries

Platform.sh, like any good PaaS, exposes a lot of useful information to applications via environment variables. The obvious parts, of course, are database credentials, but there's far more that we make available to allow an application to introspect its environment.

Sometimes those environment variables aren't as obvious to use as we'd like. Environment variables have their limits, such as only being able to store strings. For that reason, many of the most important environment variables are offered as JSON values, which are then base64-encoded so they fit nicely into environment variables. Those are not always the easiest to read.

That's why we're happy to announce all new, completely revamped client libraries for PHP, Python, and Node.js to make inspecting the environment as dead-simple as possible.

Installation

All of the libraries are available through their respective language package managers:

PHP:

composer install platformsh/config-reader

Python:

pip install platformshconfig

Node.js:

npm install platformsh-config --save

That's it, you're done.

Usage

All three libraries work the same way, but are flavored for their own language. All of them start by instantiating a "config" object. That object then offers methods to introspect the environment in intelligent ways.

For instance, it's easy to tell if a project is running on Platform.sh, in the build hook or not, or if it's in a Platform.sh Enterprise environment. In PHP:

$config = new \Platformsh\ConfigReader\Config();

$config->inValidPlatform(); // True if env vars are available at all.
$config->inBuild();
$config->inRuntime();
$config->onEnterprise();
$config->onProduction();

// Individual Platform.sh environment variables are available as their own properties, too.
$config->applicationName;
$config->port;
$config->project;
// ...

The onProduction() method already takes care of the differences between Platform.sh Professional and Platform.sh Enterprise and will return true in either case.

What about the common case of accessing relationships to get credentials for connecting to a database? Currently, that requires deserializing and introspecting the environment blob yourself. But with the new libraries, it's reduced to a single method call. In Python:

config = platformshconfig.Config()

creds = config.credentials('database')

This will return the access credentials to connect to the database relationship. Any relationship listed in .platform.app.yaml is valid there.

What if you need the credentials formatted a particular way for a third-party library? Fortunately, the new clients are extensible. They support "credential formatters", which are simply functions (or callables, or lambdas, or whatever the language of your choice calls them) that take a relationship definition and format it for a particular service library.

For example, one of the most popular Node.js libraries for connecting to Apache Solr, solr-node wants the name of a collection as its own string. The Platform.sh relationship provides a path, since there are other libraries that use a path to connect. Rather than reformat that string inline, the Node.js library includes a formatter specifically for solr-node:

const solr = require('solr-node');
const config = require("platformsh-config").config();

let client = new solr(config.formattedCredentials('solr-relationship-name', 'solr-node'));

Et voila. client is now a solr-node client and is ready to be used. It's entirely possible to register your own formatters, too, and third-party libraries can include them as well:

config.registerFormatter('my-client-library', (creds) => {
  // Do something here to return a string, struct, dictionary, array, or whatever.
});

We've included a few common formatters in each library to cover some common libraries. We'll be adding more as time goes by, and, of course, PRs are always extremely welcome to add more!

But what about my language?

We wanted to get these three client libraries out the door and into your hands as soon as possible. But don't worry; Go and Ruby versions are already in the works and will be released soon.

We'll continue to evolve these new libraries, keeping the API roughly in sync between all languages, but allowing each to feel as natural as possible for each language.

Larry Garfield
Larry Garfield