Developing software in the Real World

Implementing CORS in Zend Expressive

On a recent project, I needed to implement CORS support for my Expressive API. The easiest way to do this is to use Mike Tuupola's PSR-7 CORS Middleware. As this is a standard Slim-Style PSR-7 middleware implementation, we need to wrap it for Expressive, so we make a factory: App/Factory/CorsMiddleware.php:

We then register this in our App\ConfigProvider::getDependencies() by adding to the factories key so that it looks something like this:

If you don't… continue reading.

Customising Whoops in Expressive

I find the Whoops error handler page in Expressive quite hard to read and particularly dislike that the error message displayed in the top left is hidden if it's more than a few words long. To fix this, I discovered that you can provide a custom CSS file to the PrettyPrintHandler and then override to your heart's content! One way to do this is to add a delegator factory to add the additional functionality, so… continue reading.

Using Docker to create a MySQL server

When working on test code on my computer, I usually use the built-in PHP server (php -S) which works nicely. Every so often, I need access to MySQL and I use Docker to temporarily create a MySQL server for me. This is how I do it. The magic command is:

This creates a Docker container called "mysql" on port 3306. We pass three environment variables: MYSQL_USER, MYSQL_PASSWORD & MYSQL_DATABASE which are our credentials and… continue reading.

OuputBuffer Middleware for Expressive

When developing an Expressive application, if you use var_dump(), echo, print_r(), etc when you get this error:

This occurs after your data has been displayed and makes perfect sense as Expressive is unable to send headers as you've already started sending the body. To solve this, you need some middleware. It looks like this:

This middleware wraps all subsequent middleware in an output buffer and then either appends or prepends the contents to… continue reading.

Displaying errors in Expressive with Twig

If you're not using the Whoops error handler with Expressive and are using the Twig renderer, then you are given no information about the problem that occurred, even in debug mode. To fix this, I changed error.html.twig to this:

The new part is the within the {% if error %} block. In debug mode, error is set to the exception that was thown and is blank otherwise, so you won't leak sensitive information (as… continue reading.

"Software architecture is failing" by Alex Hudson

Alex Hudson's article, "Software architecture is failing" is a really interesting article and resonates with me as I come across this a lot. I recommend reading it. I'm very much in the camp of designing for the business requirements first and my biggest successes are the apps which solve my clients' problems. To call one of my apps "legacy" is a compliment; it means that I've written something that works and is solving real-problems for… continue reading.

Pretty print curl -i

My favourite tool for working with APIs is curl and in particular, I like using the -I switch to view the status line and headers too: This generates an output that looks like this:

What I would like to do is pretty print the body if it's JSON or XML so that it's easier to read. There are some tools out there, like jq which will format JSON, but they can't seem to cope… continue reading.

Converting a Composer dependency to git for editing

I'm adding a new feature to ZF's Problem-Details component and it's easiest to do this within the context of the application I'm developing. The component lives in vendor/zendframework/zend-problem-details and was installed using composer require so doesn't have its own git repository as the distribution zip file was used to install it. To change it to a git repository, we can use the –prefer-source option and specify a branch like this:

I now have a… continue reading.

Custom URLs for a Cloud Foundry application

Now that I have my application deployed to Cloud Foundry, I need it to work with my own domain, such as bookshelf.akrabat.com rather than slim-bookshelf.eu-gb.mybluemix.net. We can do this via the command line which is useful. To do this we need to create a domain and then we can create a route. Create a domain To create a domain, we use the command cf create-domain {organisation name} {domain name}. For me, my organisation is "19FT",… continue reading.

CORS and OpenWhisk web actions

By default, OpenWhisk will handle the relevant responses for CORS. Specifically, it will respond to an OPTIONS request with these headers:

If you need to change what is sent or you don't want to send these headers at all, then you need to do set the annotation web-custom-options to true and handle the OPTIONS header yourself. Note that if you don't set this annotation, you must not set any of these headers yourself as… continue reading.