MADEBYARIS

PHP API development for a Next.js product

5 min read
By Aris Setiawan
PHP API development for a Next.js product

PHP API development for a Next.js product is not “put JSON in a controller and hope.”

I put the write where the domain already lives. Laravel (or modern PHP) owns auth, validation, the database write, and the job queue. Next.js owns the UI and the cache that shows that write. If I cannot name who owns the write, I do not open a new endpoint.

I’m Aris Setiawan. I ship Next.js fronts and PHP backends for client work. I already wrote the App Router API routes I trust. This post is the other door: when the API is PHP, not another route.ts in the same repo.

If you want this owned on a product, that is PHP development.

Who owns the write

Who owns the write: Next.js form, PHP API, database

A Next.js form can look like it owns everything. It does not.

Next.js. Collect input. Call the API. Revalidate the tag the list page uses. Show the result. Keep Server Actions for writes that never leave this app. When the domain is already PHP, the form is a client of that API.

PHP API. Authenticate. Validate. Write once. Enqueue the slow work. Return a boring status and a small JSON body. Prefer Laravel when the product already has models, policies, and jobs there. I do not invent a second domain layer in Next to look modern.

Database. One writer path. If Next and PHP both write the same table “for speed,” you will debug race conditions on a Friday.

The split is the product. A pretty React form with a half-auth PHP dump behind it is not PHP API development. It is a leak.

When I keep Laravel behind Next.js

Next.js + Laravel + jobs

I keep Laravel (or a focused PHP API) when one of these is true:

The business rules already live in PHP. Orders, invoices, roles, reports. Rewriting that into TypeScript just to say “all Next” is a year of unpaid migration.

You need a real job queue. Emails, PDF, webhooks to vendors, retries. Laravel queues are boring and shippable. I do not fake that with a route.ts that times out at 30 seconds.

Multiple clients need the same write. A Next app, a mobile app, an admin tool. One versioned HTTP contract. Not three copies of the same validation.

You are modernizing a legacy PHP app and the UI is moving to Next first. Keep the write in PHP. Move screens. Do not dual-write.

I still use Next for the App Router tree, the cache I can name, and the hire path on Next.js development when the product is mostly that stack. This post is for the case where PHP is the API owner.

A contract I will ship

Ship vs skip for a PHP API

A PHP API endpoint I will leave in the repo looks boring on purpose.

Auth first. Session cookie for first-party, token for third-party, signature for webhooks. Fail closed. I do not return 200 on a bad signature so a vendor “stops retrying.”

One job. Create invoice. Update status. Enqueue PDF. If the handler also rewrites three tables and pings Slack, I split it. The HTTP response stays small.

Versioned path. /api/v1/... when an outside client exists. Breaking changes get a new version. I do not silently rename fields because the Next form was updated this morning.

Named errors. validation_failed, unauthorized, conflict. Not a stack dump. Not a blank 500.

Docs that match the code. Even a short OpenAPI or a Markdown table of routes. If the Next app guesses field names, the contract is already broken.

What I skip:

A god endpoint that accepts action=anything.

Leaking SQL or stack traces to the browser.

Skipping auth because “it is only called from our Next app.” Your Next app is still the internet.

Duplicating the same write as a Next Server Action and a PHP route “just in case.” Pick one owner.

How Next.js talks to it

From the Next side I keep the call boring too.

Server-side fetch to the PHP origin with the auth the API expects. Timeout I can name. Parse JSON. Map named errors to UI. After a successful write, revalidate the tag the list page uses. Same cache habit as Next.js cache on Vercel.

I do not put the PHP database password in the Next env “to skip the API.” That is how you get two writers and one outage.

For webhooks that hit PHP, Next stays out of the path. For webhooks that must touch a Next-only cache, PHP finishes the write, then a small internal call or a shared tag strategy busts what the UI shows. Name that path. Do not invent it in production.

What I will take

I take a Next.js product that needs a real PHP or Laravel API: auth, writes, jobs, a versioned contract, and a UI that does not own the database. I also take legacy PHP with a new Next front when we keep one writer.

I will not take a rewrite that turns every Laravel policy into a Server Action so the stack looks uniform on a slide.

If you want this owned, start at PHP development. Send the repo or the ticket. If the front is the main gap and the API is already fine, say so. We will pick the door that matches the write.

Tags:

Aris Setiawan

Aris Setiawan

Senior Full Stack Developer specializing in Next.js, React, and WordPress. I write about web development, performance optimization, and best practices.

Related Articles