- Knowledge
- technology
- OOP
- Tips
- Programming
- Tips
- Tutorial
- SEO
- Ranking
- Knowledge
- Special Day
- Seo
- Bug
- Data science
- Seo
- artificial intelligence
- Machine Learning
- Robotics
- happyNewYear2021
- newYearEve
- 2021
- Automation
- Smart Home
- Career
- Best Practices
- Git
- Logging
- Web Fundamentals
- DNS
- HTTPS
- Performance
- AI Tools
- ChatGPT
- Claude
- Gemini
- Laravel
- Eloquent
- MySQL
- HTTPS
- TLS
- Web Security
- Certificates
- Developer Life
- Debugging
- Docker
- DevOps
- Transactions
- Queues
- LLMs
- AI
- AI Coding
- Developer Tools
- React Native
- Expo
- Kate PMS
- Mobile Apps
- Laravel
- Authentication
- Sanctum
- Cookies
- API Design
- Payments
- Idempotency
- DeepSeek
- Open Source AI
- LLMs
- AI News
- Git
- Version Control
- AI Coding
- Prompting
- PHP
- Checklist
- MCP
- AI Agents
- OpenAI
- Architecture
- Microservices
- Modular Monolith
- Estimation
- Developer Life
- Project Planning
- Humour
- OAuth
- OpenID Connect
- Authentication
- Embeddings
- Vector Search
- RAG
- pgvector
- OpenAI
- GPT-4.1
- Codex CLI
- Events
- Testing
- Clean Code
- Maintainability
- Code Review
- Webhooks
- API
- Security
- Claude Code
- Workflow
- AI
- LLM
- Prompt Injection
- Mobile
- React
- Networking
- TCP
- UDP
- HTTP/3
- CLAUDE.md
- AWS
- Cloud Security
- Backups
- PHPUnit
- Software Engineering
- Leadership
- Communication
- RAG
- Embeddings
- AI Engineering
- IT Infrastructure
- Networking
- Access Control
- CI/CD
- GitHub Actions
- Gemini CLI
- Claude Code
- JavaScript
- Async/Await
- Node.js
- Promises
- Security
- Cryptography
- Passwords
- MySQL
- Database
- Vibe Coding
- Software Quality
- DNS
- Code Reading
- Onboarding
- Productivity
- Background Jobs
- Developer Humour
- Estimates
- Dev Life
- JWT
- o3-mini
- DeepSeek R1
- Rate Limiting
- Kate PMS
- E-Signing
- Audit Trail
- REST
- GraphQL
- API Design
- Laravel 12
- Upgrade Guide
- Open Source
- Self-Hosting
- Task Scheduling
- Cron
- Secrets
- CORS
- PHP
- PHP-FPM
- OPcache
- GitHub Copilot
- Software Architecture
- Engineering
- TypeScript
- JavaScript
- Type Safety
- AI Security
- React Native
- Product Design
- AI Agents
- Kiro
- Queues
- Redis
- RabbitMQ
- AWS SQS
- Nginx
- Apache
- GPT-5
- gpt-oss
- Clean Code
- Architecture
- Naming
- Documentation
- Career
- ADR
- Teamwork
- Supply Chain
- Kate HRM
- HR Software
- Permissions
- System Design
- Pagination
- SSH
- Linux
- Big O
- Databases
- Laravel Boost
- MCP
- Developer Skills
- Validation
- Databases
- Indexes
- Code Quality
- Deployment
- Developer Humour
- Feature Flags
- Code Review
- Pull Requests
- Docker
- Cursor
- Authorization
- RBAC
- Gemini
- Long Context
- PHP 8.4
- Caching
- Dependency Injection
- Web Performance
- Browser
- CSS
- Database
- Migrations
- ChatGPT
- AI for Developers
- Monitoring
- On-Call
- REST
- Backend
- SQL
- NoSQL
- Database Design
- Coding Agents
- Claude 4
- API Resources
- REST API
- Load Balancing
- Scaling
- AWS
- AI Tools
- Claude
- Sora 2
- CTE
- 2FA
- TOTP
- Programming Languages
- Prompts
- Developer Workflow
- API Gateway
- APIs
- Passport
- API Auth
- Learning
- Burnout
- Developer Growth
- Web Development
- SEO
- Kate Mall
- ChatGPT Atlas
- Agent Skills
- Middleware
- Laravel 12
- Collections
- Context Window
- Monitoring
- Commit Messages
- Self Review
- Growth
- Regex
- Programming Basics
- Text Processing
- Database Design
- Normalization
- Linux
- Server Security
- Linux Foundation
- Open Standards
- Legacy Code
- Documentation
- AI Workflow
- File Uploads
- Test Data
- Hashing
- Performance
- Caching
- Enums
- Scope Creep
- Estimation
- Codex
- Gemini CLI
- Timezones
- Carbon
- Bugs
- PHP 8.5
- Gemini 3
- GPT-5.1
- Data Integrity
- Event Loop
- Async
- Opus 4.5
- AI Models
- React
- Forms
- Frontend
- Backups
- AI Images
- DALL-E
- Midjourney
- Race Conditions
- Concurrency
- Legacy Code
- Refactoring
- Senior Engineer
- Scope
- LLM
- CDN
- Web
- Sub-Agents
- Soft Deletes
- Audit Log
- Concurrency
- AI Learning
- NestJS
- AI Evals
- Policies
- SPF DKIM DMARC
- Unicode
- UTF-8
- Knowledge Graph
- Value Objects
- Technical Debt
- Feature Flags
- Laravel Pennant
- Deployment
- Copilot
- Composer
- Dependencies
- Artisan
- Automation
- AWS S3
- Object Storage
- Cloud
- Small Language Models
- Ollama
- Production
- Sessions
- HTTP
- Mentoring
- SQL
- Virtual Machines
- Web Development
- HTTP/2
- QUIC
- Web Performance
- AI Integration
- LLM API
- SOLID
- OOP
- Hosting
- Serverless
- Merge Conflicts
- Temperature
- AI Development
- Reverse Proxy
- Nginx
- Infrastructure
- Verification
- Passkeys
- WebAuthn
- Teams
- Communication
- Stakeholders
- Monorepo
- CI/CD
- Versioning
- JSON Schema
- Livewire
- Inertia
- Meetings
- Distributed Systems
- Privacy
- Full-Stack
- T-Shaped Skills
- Money
- Notifications
- Web Security
- HTTP Headers
- CSP
- Function Calling
- Load Testing
- k6
- Data Extraction
- Debugging
- WebSockets
- SSE
- Real-Time
- Laravel Reverb
- Infrastructure as Code
- Terraform
- Side Projects
- Laravel Pint
- OpenAPI
- Swagger
- UX
- Multimodal
- Jest
- Pair Programming
- APIs
- Rate Limiting
- Resilience
- Dev Humour
- Design Tokens
- JWT
- API Keys
- Sessions
- PHPStan
- Rector
- Incidents
- Reporting
- Dashboards
- Zero Trust
- IAM
- Search
- Laravel Scout
- Junior Developers
- Mentoring
- Images
- WebP
- AVIF
- Bug Reports
- Let's Encrypt
- Design Docs
- Software Design
- Observers
- Replication
- Accountability
- Data Structures
- Reliability
- LLM Memory
- Error Handling
- Payments
- Payment Gateway
- Webhooks
- PCI DSS
- Observability
- OpenTelemetry
- Personal Brand
- Writing
- Conventions
- Dates
- Scheduling
- Disaster Recovery
- Compression
- Brotli
- Deadlines
- Developer Habits
- State Machines
- Tech Roles
- UUID
- ULID
- Horizon
- Planning
- Engineering Culture
- Ownership
- Soft Skills
- Socialite
- Cost Control
- Collations
- Unicode
- Octane
- PostgreSQL
REST vs GraphQL: An Honest Comparison From a Laravel Developer
About Post
Every few months someone declares REST dead and GraphQL the future. Every few months someone else writes a post about ripping GraphQL out and going back to REST. Both groups are usually right about their own project, and wrong about yours.
I build APIs in Laravel for web portals and mobile apps, and I've watched teams pick each one for the wrong reasons. So here's an honest comparison: what each one really solves, what it quietly costs, and how to choose.
The problem GraphQL was built to solve
Imagine a tenant app's home screen. It needs the current contract's end date, the tenant's name, and the last three payments. With a typical REST API, that might be:
GET /api/contracts/42 -> returns 30 fields, you need 1
GET /api/tenants/7 -> returns 25 fields, you need 1
GET /api/contracts/42/payments -> returns all of them, you need 3
That's both classic REST complaints in one screen:
- Over-fetching: you download far more data than you use. On a weak mobile connection, that matters.
- Under-fetching: one screen needs several round trips, often one after another.
With GraphQL, the client asks for exactly the shape it wants, in one request:
query {
contract(id: 42) {
endDate
tenant { name }
payments(last: 3) { amount paidAt }
}
}
The response mirrors the query. No extra fields, no extra trips. When you have many different clients with different needs, that's genuinely powerful.
What GraphQL costs you
Here's the part the conference talks skip.
Caching gets harder
REST works with HTTP caching out of the box. GET /api/units/12 is a URL: browsers, CDNs and proxies all know how to cache it, with ETag and Cache-Control doing the rest.
GraphQL usually sends every query as a POST to one endpoint. To HTTP, every request looks the same, so that free caching layer disappears. You can get some back with persisted queries sent over GET, or client-side caches like Apollo's, but it's work you didn't have to do before.
N+1 queries move into your resolvers
Ask for 50 contracts with their tenant's name, and a naive resolver runs one query for the contracts and then one per contract for the tenant. 51 queries. It's the same N+1 problem we fight in Eloquent, but now the client decides the shape of the query, so you can't just add one with() in a controller.
The fix is batching, usually with the DataLoader pattern: collect all the tenant IDs requested in one pass, then load them in a single query. In Laravel, the Lighthouse package batches relationship loading for its relation directives, which helps a lot. But you have to know it's there and keep custom resolvers in line.
Security needs new thinking
With REST, each endpoint has a known cost. With GraphQL, a client can write a deeply nested query that asks for contracts, their tenants, their contracts, their payments, and so on. You need query depth and complexity limits, and authorization on fields and types, not just on routes.
More moving parts
A schema, resolvers, a GraphQL server library, client tooling, and a team that understands all of it. Error handling is different too: a GraphQL response often comes back as HTTP 200 with an errors array inside, which surprises monitoring tools that only look at status codes.
Side by side
| REST | GraphQL | |
|---|---|---|
| Data shape | Decided by the server per endpoint | Decided by the client per query |
| Round trips per screen | Often several | Usually one |
| HTTP caching | Built in | Needs extra work |
| N+1 risk | In controllers, easy to spot | In resolvers, needs batching |
| Typed contract | Optional (OpenAPI) | Built in (the schema) |
| Learning curve | Low | Medium |
| Laravel support | First-class (routes, API resources) | Via packages like Lighthouse |
REST can fix most of its own problems
Before switching paradigms, notice that the REST complaints have REST answers:
- Over-fetching: API resources that return only what clients use, or sparse fieldsets like
?fields=id,name. - Under-fetching: an
?include=tenant,paymentsparameter backed by eager loading, or a purpose-built endpoint for an important screen (sometimes called a backend-for-frontend). - Typed contracts: an OpenAPI spec, which also gives you generated docs and clients.
A dedicated GET /api/tenant/home endpoint that returns exactly what the home screen needs is not a hack. It's often the simplest, fastest and most cacheable answer.
My default: REST, with good resources and an OpenAPI spec, until I can name the specific problem GraphQL would solve for this project. "It's more modern" is not a problem.
When GraphQL earns its place
- Many different clients (web, several mobile apps, partners) need very different slices of the same data.
- Frontend teams are blocked waiting for backend changes to every endpoint.
- The data is a rich graph that clients explore in unpredictable ways.
- You're aggregating several backend services behind one API.
When REST is enough (which is often)
- One web app and one mobile app, built by the same team.
- Mostly CRUD with a few well-known screens.
- Public or cache-heavy data where HTTP caching saves real money.
- A small team that would rather ship features than maintain a schema layer.
Neither choice is permanent, either. Plenty of teams run REST for most things and add GraphQL for the one area where clients really need flexibility.
Which one is your team using right now, and if you could choose again from scratch, would you pick the same?

Be first to comment it...