TJ Miller

Some thoughts and ramblings, mostly about code.

Read this first

Verifying Laravel Version Compatibility

I’ve been working with Honeybadger to build a new set of PHP integrations. I would like to write more about that soon, however, I feel like I’ve stumbled across something that could be useful to others. I wanted to share it as soon as I could.

For the Laravel package, I was aiming for Laravel 5.5 and newer support as it is the latest LTS version. I feel like it makes sense to support down to LTS unless it becomes too complex to do so or you are leveraging features that just don’t exist in the older versions.

In hindsight, I don’t think that I actually ever tested it against a 5.5 install. I relied on the CI process to make those verifications for me. I use orchestra/testbench to aid in the testing workflow. I scaffolded the project with spatie/skeleton-php. The Travis configuration I was using seemed to work well but in hindsight, I think it really only works well if you are...

Continue reading →


Abstracting Request Keys

In an API’s codebase, it’s a good idea to abstract the keys for the requests and responses on top of your data layer. This is a key step to making it easier for your codebase to evolve and still uphold your API contract.

In Laravel we have Resource Responses to help abstract our model data for responses. For request data, I wanted a lightweight key mapping to help add a little abstraction layer.

First I created a little Request macro:

macro

Now you can use it in your controllers to map from request data to domain data.

controller

One thing I’ll still need to figure out is mutating nested keys, but I’ll cross that bridge when I get there!

Get the code from this post.

Continue reading →


Sentry Logging in Laravel

laravel+sentry.png

There are a few reasons why I just hooked Sentry into the Laravel logging on my current project:

  • It’s hosted using Docker (highly available, multiple instances) and I need a central place to capture application logs
  • There are instances where I log messages that aren’t necessarily exceptions and want visibility
  • I’m already using Sentry for exception capturing

This was pretty easy to hook up. Let’s dive in…

 Setup

01-LogServiceProvider.php

Note: You can add some additional fields to the LineFormatter. See the “Customization” section below.

Then you need to add the provider to your config/app.php file:

02-app.php

 Usage

Now anything that gets logged will be forwarded to Sentry. For example, you could use something like the following in your application to explicitly create a log entry.

03-snippet.php

“Unknown foo returned from the example service” will become the title of the entry on the Sentry project and you can find the...

Continue reading →


Linking Vessel Projects Together

Vessel is a fantastic project put together by Chris Fidao under the Shipping Docker label. (if you’re looking to get started with Docker you should really check out Shipping Docker) One of the things I love about Vessel is that its tightly focused and will jump-start local Laravel development with Docker in minutes.

I’m not going to go into detail about how to get started with Vessel in this article, go check out the docs.

 Diving In

Let’s say we have two Laravel projects that we need to communicate together at a server level. For the purpose of this article, we’ll have a web app that needs to consume a back-end service user account service.

Vessel will generate a docker-compose.yml file that looks like:

03-docker-compose.yml

In order to link the two projects together, we will need to create a docker network that both projects can use to communicate through.

Now we need to update both projects docker-c...

Continue reading →


Using Middleware to Configure a Service Class

I was doing some refactors to an API that I’m building and stumbled across a bucket of duplication.

Note: I’m going to abstract away a lot of the domain for the examples.

I happen to be using explicit route model binding, figured I should share that for some context:

01-RouteServiceProvider.php

So here is where I was finding heaps of duplication…

02-ResourceController.php

This pattern was repeated in several controllers. So what I ended up doing was extracting the configuration into a middleware.

03-GatewayMiddleware.php

In order for this to work, I needed to ensure that the IOC Container had the Gateway service bound as a singleton so it would always resolve the same instance every time its requested.

04-AppServiceProvider.php

Then I was able to refactor all my controllers.

05-ResourceController.php

This feels a lot cleaner to me, now the controllers are really only concerned with the specific details necessary for handling the request.

Now, how do we test this? Check out my post on testing...

Continue reading →


Separate Interactive Test Suites

On a recent Full Stack Radio episode, Adam Wathan and Taylor Otwell were talking about testing Laravel applications. During the episode, they spoke about isolating interactive integration tests from your normal testing e.g. payment gateways, third-party integrations. One use case would be as contract tests for fakes (really test doubles in general) to mitigate “API drift”.

I’m currently working on an HTTP API that interacts with physical credit card payment terminals and proxies/transforms the responses. I have integration tests for my API controller responses and didn’t want to have to physically interact with the terminal every time, so I built a TerminalGatewayFake test double with hard-coded responses. After each gateway update, we run the “Interactive” test suite to ensure the fakes and real responses line up.

There are a few ways you can isolate these tests either through manual...

Continue reading →


An Approach to Testing Middleware

I’ve always tested middleware in one of two ways, a unit test with mocks and asserting the callback in the handle method or integration tests on application routes.

 Unit Testing

The problem with unit testing is that you don’t have any visibility into if the middleware is actually active and you also don’t know how it will function as the request is passed through other active middleware.

 Integration Testing

Using integration tests on application routes resolves some of the issues with unit testing middleware but it makes it a little bit harder to make assertions on how the middleware is actually functioning. I also found myself wanting to constantly verify that the middleware was active and working on each of my application routes.

 Testing the Middleware

I wanted to find a simple approach that verified the following:

  • Middleware is active, and configured correctly (global, group...

Continue reading →