Planning a Custom Laravel Application: Database and API Decisions

#laravel #php #database #api #architecture #custom development

Most Laravel projects go wrong before a single line of code is written.

Not because the developer is incompetent, and not because the business requirements are unclear. They go wrong because the critical architectural decisions — the ones that determine whether an application can grow cleanly for five years or needs a rewrite in eighteen months — are made by default rather than by choice.

Nobody decides to store money as a floating-point number. It just happens, because nobody explicitly decided not to. Nobody decides to build an API that cannot be versioned. It just happens, because nobody asked the question early enough.

This guide is about making those decisions explicitly, before the codebase locks them in.

The Database Is Not a Detail — It Is the Architecture

The first thing I want to challenge is a common misconception: that the database is something you figure out during development, alongside the code. In a custom Laravel application, the database is the architecture. Everything else, the controllers, the views, the business logic, is just an interface to the data.

If the database structure is wrong, the application is wrong. You can refactor code relatively cheaply. Restructuring a live database that has two years of real customer data in it is genuinely dangerous and extremely expensive.

So we get the database right first. Here is how.

Decision 1: Do You Need a Full Audit Trail?

This is the first question I ask every client, and the answer determines a significant portion of the database architecture.

An audit trail means recording not just the current state of data, but every change made to it over time. Who changed it? What did it look like before? When did the change happen?

For some businesses, this is optional. For others, it is non-negotiable. A financial platform cannot just show you the current balance; it must show every transaction that produced that balance. A medical records system cannot just show the current medication; it must show every prescription change and who authorized it. A legal document management system must retain every version of every document indefinitely.

If your business operates in a regulated industry, or if "we need to know who changed that and when" is a question that comes up regularly, you need an audit trail baked into the architecture from day one.

In Laravel, this is typically implemented using a package like spatie/laravel-activitylog, combined with careful thought about which models need full history tracking versus which only need a simple updated_by timestamp. Adding this to an existing application is possible, but adding it correctly, meaning retroactively creating a history for data that was never tracked, is practically impossible.

Decision 2: Will This Application Ever Have a Mobile App or Third-Party Consumer?

A web application and an API-first application look very similar from the outside. Underneath, they are structured very differently.

A traditional web application serves HTML pages. The server processes a request, fetches data from the database, renders it into a Blade template, and sends the finished HTML to the browser. Everything is tightly coupled to the web browser as the only consumer.

An API-first application serves data. The server processes a request, fetches data from the database, and returns a clean JSON response. Anything can consume that: a web browser running React or Vue, a mobile app on iOS or Android, a third-party business partner, an automated reporting tool.

If there is even a reasonable chance that your business will want a mobile app in the next three years, or that you will eventually want to open up your data to other systems, building API-first from the beginning is almost always the right call. The web dashboard consumes the same API as the eventual mobile app. The additional development cost upfront is minimal, and the payoff when the mobile requirement arrives is enormous.

If you build a traditional web application and then need to add a mobile API eighteen months later, you are essentially rebuilding the application's data access layer from scratch while keeping the existing system running. It is one of the most disruptive technical projects you can undertake on a live application.

Decision 3: What Work Cannot Happen While the User Waits?

Every application has tasks that take time. The question is whether the user should wait for that time to pass, or whether the application should acknowledge the request instantly and process it in the background.

This distinction, between synchronous and asynchronous processing, shapes the entire feel of an application. An application that makes users stare at loading bars feels slow and unreliable, even if the underlying server is perfectly capable. An application that acknowledges requests instantly and processes them in the background feels snappy and professional, even if the total processing time is identical.

Laravel's Queue system is the mechanism for this. When you push a task to a Queue, Laravel writes a job record to a database table or a Redis instance, returns an immediate response to the user, and then processes the job in the background through a separate worker process. The user gets their success message within milliseconds. The heavy work happens invisibly behind the scenes.

Common tasks that should always be queued in a business application:

  • Sending any email or SMS notification
  • Generating PDF or Excel reports from large datasets
  • Processing uploaded CSV files
  • Making outgoing API calls to third-party services (payment gateways, shipping APIs, CRM synchronization)
  • Sending webhooks to external systems
  • Running complex calculations or data aggregations

The rule of thumb is simple: if a task could theoretically take more than half a second in a worst-case scenario, it should probably be queued. Decide this at the architecture stage, not when users are already complaining that the application feels slow.

Decision 4: How Will You Handle Data That Cannot Be Deleted?

In almost every business application, there is data that legally or contractually cannot be permanently deleted, even when a user requests it. An invoice must be retained for tax purposes. An order record must be kept for dispute resolution. A user account might need to be deactivated rather than deleted to preserve the integrity of historical records that reference it.

Laravel provides Soft Deletes as a built-in mechanism for this. Instead of actually removing a database row, a soft delete simply marks it with a deleted_at timestamp. The record becomes invisible to normal queries but remains in the database. You can restore it, reference it in historical reports, and satisfy legal retention requirements without building a complex archive system.

The decision about which models need soft deletes must be made during the architecture phase. Applying soft deletes to a model mid-project, after data already exists, requires careful migration work to ensure existing queries still behave correctly.

The Cost of Deciding Too Late

Every one of these decisions has something in common: they become dramatically more expensive the later they are made. An audit trail built on day one of the project adds perhaps ten percent to the initial development time. An audit trail bolted onto a live application eighteen months later can take weeks of careful, risky work to implement correctly without breaking existing functionality.

The purpose of this architectural planning phase is to make explicit decisions, document them, and ensure the entire development team builds toward the same foundation. It does not have to be a lengthy formal process. In most cases, a focused two-hour conversation with the right questions, guided by someone who has built similar applications before, is enough.

If you are about to start a custom Laravel application and want to ensure the architecture decisions are made correctly from the beginning, the custom Laravel development services page explains how the scoping and architecture phase of my engagements works.


Prakash Tank

Prakash Tank

Full-Stack Architect & Tech Enthusiast. Passionate about building scalable applications and sharing knowledge with the community.