APIs, architecture and PHP, taught from production.
I fix slow, unreliable APIs for a living. This is where I write down what that work teaches, in whichever format suits how you learn.

Steve McDougall · PHP-FIG Core Committee · php[architect] columnist
Spoken at Nordic APIs Platform Summit, API Platform Conference, Laravel Live Pakistan and 9 meetups
{
"specversion": "1.0",
"id": "9c8b2e1a-1f4d-4f0f-9e3a-2b6a5f0d1c77",
"source": "/billing/stripe",
"type": "com.acme.subscription.renewed.v1",
"subject": "cus_01HZY",
"time": "2026-08-24T09:14:22Z",
"datacontenttype": "application/json",
"data": {
"plan": "team",
"amount": 4900,
"currency": "gbp"
}
}Accepting Data You Don't Control
Something outside your control needs to send you data: webhooks from a payment provider, callbacks from a partner integration, telemetry from devices in the field, analytics events from a front end team, domain events from a service you did not write. Whatever it is, you didn't design the payload, you can't version it on your own schedule, and you'll hear about changes to it after they ship rather than before.
Start here
Pick a subject. Get a route through it.
How APIs outgrow the design they shipped with, and what to fix first.
- 1Accepting Data You Don't ControlWebhooks and callbacks you did not design. An ingest server in Laravel 13 that owns the envelope, stores the payload whole, and validates where failure means a retry, not data loss.14 min read
- 2When CRUD Isn't Enough: How Real APIs Outgrow Their DesignMost Laravel APIs start as clean CRUD systems. This article walks through why that breaks down, and how an action-based design fixes the mess.10 min read
- 3Building Bulletproof Laravel APIs using Schema-First Contract ValidationStop letting undocumented fields into your Laravel API. Write the JSON Schema first, then enforce it in middleware, DTOs, and your Pest test suite.10 min read
- 4The Tips Behind API Artisan: Building Laravel APIs Developers Actually Want to UsePractical tips for building Laravel APIs developers trust: contract-first design, versioning, RFC 9457 errors, idempotency and more. Free book inside.13 min read
4 steps · about 47 minutes · everything on API Design →
Recognising the pattern you already live inside, and pricing the exit.
- 1The Rewrite You Should Not DoYou have run the diagnostics and you have a list. Now price the three options honestly, including the one where you do nothing, which is right more often than the other two put together.8 min read
- 2The Second Pattern: BulkheadCarrier B did not go down, it got slow, and every worker sat inside an eleven second call that returned a valid 200. Circuit breakers ask the wrong question about that.13 min read
- 3Your Test Suite Is an Architecture ReportA slow Laravel test suite gets treated as a tooling problem. It is usually a coupling measurement, and the number worth watching is not how long the suite takes.8 min read
- 4Nobody Wants To Touch That ModelEvery Laravel codebase has a model people route around. Counting its lines is the least useful thing you can do to it, and extracting traits is how the count gets hidden rather than fixed.8 min read
4 steps · about 37 minutes · everything on Architecture →
The language got good. Most code has not caught up with it.
- 1Fibers Plus the Polling API: What Async PHP Actually Looks Like NowFibers give PHP concurrency. The Polling API gives it native epoll and kqueue. Here's how to build on both, with honest benchmarks.12 min read
- 2The Object Design Style Guide for PHP 8.5 - Discipline without frictionHow PHP 8.5 absorbs Noback's Object Design Style Guide patterns directly into syntax, eliminating ceremony.12 min read
- 3Testing Actions, Not MocksMocking your own Actions tests the wiring, not the behaviour. How I test Laravel Action classes for real with Pest, and where fakes still belong.9 min read
- 4The PSR Standards You Are Probably IgnoringFive PSR standards that most PHP developers skip. Master them and write code that works anywhere, tested easily, and tied to nothing.12 min read
4 steps · about 45 minutes · everything on PHP & Laravel →
Deploys, local environments, CLIs, and where agents actually help.
- 1Designing CLIs people want to useAPI design is a user experience problem and nobody argues any more. Then we build a CLI and forget all of it. Cobra defaults, which ones are wrong, and what I do instead.22 min read
- 2Controlling Code Quality When an Agent Writes Your LaravelSpecs, ADRs and path-scoped rules. The three layers of context I build around an agent so it writes Laravel the way my codebase does, not the way every tutorial does.14 min read
- 3One Host, Twenty-One Files: A NixOS Flake That Stays Out Of Your WayHow auto-imported flake-parts modules, wrapped desktop packages, and a single base16 palette file shape one NixOS config - and where each one bites.13 min read
- 4MCP Goes Stateless: What Changed and Why It MattersThe Streamable HTTP transport replaced HTTP+SSE and quietly made MCP servers stateless. Here is what that means, how the new transport works, and why it unlocks serverless and edge deployments.12 min read
4 steps · about 61 minutes · everything on Shipping & Tooling →
The job changes from writing code to deciding what gets written.
- 1Stop Writing Code FirstThink through requirements, assumptions, and structure before you open your editor.5 min read
- 2Technical Debt: When to Fix, When to ShipTechnical debt is inevitable. What matters is managing it deliberately. Here is a practical framework for prioritisation and stakeholder communication.10 min read
- 3Building Psychological Safety in EngineeringHow to create a culture where engineers feel safe to take risks, speak up, and make mistakes without fear of punishment.10 min read
- 4The Mid-Level MindsetA practical mindset shift for turning thinking-first habits into mid-level engineering judgment.6 min read
4 steps · about 31 minutes · everything on Engineering Leadership →
Watch
The work, at the pace it happens.
Steve is one of the most thorough and thoughtful educators I've seen. He puts in a ton of effort and it clearly shows.
“Steve is an awesome writer and communicator, he can take complex problems and communicate them in a way that anyone can understand.”
“Steve is one of the best tech writers and engineers I've had the pleasure of working with. I hate to even write this testimonial because I don't want to share him. He's the best in the biz.”
Go deeper
Longer arguments, and patterns to look up.
Nine architecture patterns that rarely get named in PHP, and one article on the ones that are not worth it. Each starts with the obvious move, finds the exact point it breaks, then reaches for the pattern that fits. Built in Tempest, aimed at anyone writing PHP REST APIs.
A diagnostic series for Laravel codebases that are clean, modern, well tested, and still expensive to work in. Each part starts from a symptom a team actually reports, works back to the structural cause, and prices the fix honestly, including the times the answer is to leave it alone.
- 01Your Test Suite Is an Architecture Report
- 02Every Feature Touches Ten Files
- 03Nobody Wants To Touch That Model
- 04The Job And The Controller Disagree
- Cursor-based pagination for stable listsintro
- Expandable relationships with sparse expansionsintermediate
- Deferred writes with the Outbox Patternintermediate
- Idempotency keys for safe retriesintro
- Bulk updates via async jobsintermediate
- Receiving webhooks in Laravelintermediate
- Webhook event delivery with signed payloadsintermediate
Latest
- 07 OctArticleHow to Write Specs, RFCs and ADRs
- 07 OctArticleWhat Actually Constrains a Coding Agent
- 06 OctArticleSending And Receiving Webhooks In Laravel
- 05 OctArticleMy business lives in my vault now
- 02 OctArticleMy clients live in a folder now
- 01 OctArticleBuilding a home-education platform with Laravel 13, Inertia and React, and shipping it to Laravel Cloud
Newsletter
New lessons, every couple of weeks.
Articles, videos and guides as they land. Nothing else.



