RESTful API Development in PHP
Design and build secure, standard RESTful APIs in PHP. Handle headers, request methods, JSON formatting, status codes, and rate limiting.
Downloaded from PrepIQ (https://prepiq.online)
Q1. What is REST and what makes an API RESTful?
REST (Representational State Transfer) is an architectural style for designing networked applications using stateless, resource-based communication over HTTP.
| REST Principle | Meaning |
|---|---|
| Statelessness | Each request contains all info needed; server stores no client session |
| Resource-based | URLs represent resources (nouns), not actions (e.g. /users not /getUsers) |
| Uniform interface | Standard HTTP methods (GET, POST, PUT, DELETE) map to operations |
| Client-server separation | Frontend and backend evolve independently |
An API is 'RESTful' when it follows these conventions consistently, using proper HTTP methods and status codes rather than custom action-based endpoints.
Q2. What are the main HTTP methods used in REST APIs and their purposes?
| Method | Purpose | Idempotent |
|---|---|---|
| GET | Retrieve a resource | Yes |
| POST | Create a new resource | No |
| PUT | Replace a resource entirely | Yes |
| PATCH | Partially update a resource | No |
| DELETE | Remove a resource | Yes |
Route::get('/api/users', [UserController::class, 'index']);
Route::post('/api/users', [UserController::class, 'store']);
Route::put('/api/users/{id}', [UserController::class, 'update']);
Route::delete('/api/users/{id}', [UserController::class, 'destroy']);Idempotent means calling the method multiple times produces the same result as calling it once - important for retry logic on unreliable networks.
Q3. What HTTP status codes should a REST API return and when?
| Code | Meaning | When to use |
|---|---|---|
| 200 OK | Success | Successful GET, PUT, PATCH |
| 201 Created | Resource created | Successful POST |
| 204 No Content | Success, no body | Successful DELETE |
| 400 Bad Request | Invalid input | Validation failures |
| 401 Unauthorized | Not authenticated | Missing/invalid token |
| 403 Forbidden | Authenticated but not allowed | Permission denied |
| 404 Not Found | Resource doesn't exist | Invalid ID |
| 422 Unprocessable Entity | Semantic validation error | Field-level validation errors |
| 500 Internal Server Error | Server-side failure | Unhandled exceptions |
return response()->json(['error' => 'User not found'], 404);
Q4. How do you handle API authentication using tokens (e.g. Laravel Sanctum/JWT)?
Token-based authentication issues a token on login that the client sends with every subsequent request, avoiding the need for server-side session state.
// Login - issue token
Route::post('/login', function (Request $request) {
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
$token = $user->createToken('api-token')->plainTextToken;
return response()->json(['token' => $token]);
});
// Protecting routes
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});| Header sent by client | Value |
|---|---|
| Authorization | Bearer <token> |
Q5. How do you version a REST API and why is it important?
Versioning lets you evolve an API without breaking existing clients that depend on the current behavior.
| Strategy | Example | Trade-off |
|---|---|---|
| URI versioning | /api/v1/users | Simple, visible, but clutters URLs |
| Header versioning | Accept: application/vnd.api.v1+json | Clean URLs, less discoverable |
| Query parameter | /api/users?version=1 | Easy but easy to forget/omit |
Route::prefix('v1')->group(function () {
Route::apiResource('users', UserV1Controller::class);
});
Route::prefix('v2')->group(function () {
Route::apiResource('users', UserV2Controller::class);
});URI versioning is the most common approach because it's explicit and easy for consumers to understand at a glance.
Q6. How do you implement pagination in a REST API?
Pagination limits how many records are returned per request, improving performance and response size for large datasets.
public function index(Request $request)
{
$perPage = $request->get('per_page', 15);
$users = User::paginate($perPage);
return response()->json($users);
}
// Response includes:
// data, current_page, last_page, per_page, total, next_page_url, prev_page_url| Pagination type | How it works | Best for |
|---|---|---|
| Offset-based | ?page=2&per_page=15 | Simple UIs with page numbers |
| Cursor-based | ?after=eyJpZCI6MTB9 | Large, frequently changing datasets |
Q7. How do you validate incoming request data in a PHP REST API?
Validation ensures incoming data meets expected rules before it's processed, returning clear errors otherwise.
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'age' => 'nullable|integer|min:18',
]);
$user = User::create($validated);
return response()->json($user, 201);
}
// On failure, Laravel automatically returns:
// 422 Unprocessable Entity with { "errors": { "email": ["..."] } }Using Form Request classes (php artisan make:request) keeps validation logic out of controllers for larger applications.
Q8. What is CORS and how do you handle it in a PHP API?
CORS (Cross-Origin Resource Sharing) is a browser security mechanism that blocks JavaScript from making requests to a different domain unless the server explicitly allows it via response headers.
header('Access-Control-Allow-Origin: https://myfrontend.com');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}| Header | Purpose |
|---|---|
| Access-Control-Allow-Origin | Which domains can access this API |
| Access-Control-Allow-Methods | Which HTTP methods are permitted |
In Laravel, this is typically handled via the built-in cors middleware and config/cors.php rather than manual headers.
Q9. What is rate limiting and how do you implement it in a PHP API?
Rate limiting restricts how many requests a client can make in a given time window, protecting the API from abuse and overload.
// Laravel built-in throttle middleware
Route::middleware('throttle:60,1')->group(function () {
Route::get('/api/data', [DataController::class, 'index']);
});
// Allows 60 requests per 1 minute per user/IP| Response header | Meaning |
|---|---|
| X-RateLimit-Limit | Max requests allowed |
| X-RateLimit-Remaining | Requests left in current window |
| Retry-After | Seconds until limit resets (on 429) |
When the limit is exceeded, the API should return 429 Too Many Requests.
Q10. What are best practices for designing consistent JSON API responses?
A consistent response structure makes an API predictable and easier for consumers to parse, regardless of success or failure.
// Success response
{
"success": true,
"data": { "id": 1, "name": "John" },
"meta": { "page": 1, "total": 50 }
}
// Error response
{
"success": false,
"message": "Validation failed",
"errors": { "email": ["The email field is required."] }
}| Practice | Why it matters |
|---|---|
| Consistent envelope (success/data/errors) | Predictable parsing on client side |
| snake_case or camelCase consistently | Avoids confusion across endpoints |
| Never leak stack traces | Security - avoid exposing internals |
| Include pagination meta | Helps clients build UI navigation |
RESTful API Development in PHP
Design and build secure, standard RESTful APIs in PHP. Handle headers, request methods, JSON formatting, status codes, and rate limiting.
What is REST and what makes an API RESTful?
REST (Representational State Transfer) is an architectural style for designing networked applications using st...
What are the main HTTP methods used in REST APIs and their purposes?
MethodPurposeIdempotentGETRetrieve a resourceYesPOSTCreate a new resourceNoPUTReplace a resource entirelyYesPA...
What HTTP status codes should a REST API return and when?
CodeMeaningWhen to use200 OKSuccessSuccessful GET, PUT, PATCH201 CreatedResource createdSuccessful POST204 No...
How do you handle API authentication using tokens (e.g. Laravel Sanctum/JWT)?
Token-based authentication issues a token on login that the client sends with every subsequent request, avoidi...
How do you version a REST API and why is it important?
Versioning lets you evolve an API without breaking existing clients that depend on the current behavior.Strate...
How do you implement pagination in a REST API?
Pagination limits how many records are returned per request, improving performance and response size for large...
How do you validate incoming request data in a PHP REST API?
Validation ensures incoming data meets expected rules before it's processed, returning clear errors otherwise....
What is CORS and how do you handle it in a PHP API?
CORS (Cross-Origin Resource Sharing) is a browser security mechanism that blocks JavaScript from making reques...
What is rate limiting and how do you implement it in a PHP API?
Rate limiting restricts how many requests a client can make in a given time window, protecting the API from ab...
What are best practices for designing consistent JSON API responses?
A consistent response structure makes an API predictable and easier for consumers to parse, regardless of succ...