Capstone: JSON API
| The spec | |
| API routes | |
| Shape with resources | |
| Test the endpoints |
The spec
Turn the blog into a JSON API: the same posts, now served as data for mobile apps and JavaScript front ends. Endpoints list posts, show one post, and store a new one, all answering with JSON and proper status codes.
GET /api/posts - list all posts GET /api/posts/1 - show one post POST /api/posts - store a new post
API routes
API routes live in the api routes file, which adds the api prefix and stateless middleware automatically. Resource-style pairs keep the surface small: one line per action, one controller per model.
Route::get("/posts", [PostController::class, "index"]); Route::get("/posts/{post}", [PostController::class, "show"]); Route::post("/posts", [PostController::class, "store"]);
Shape with resources
API resources decide exactly which fields leave the server. Hide internal columns, keep the field names stable, and never leak timestamps or tokens that the client did not ask for - apps in the wild cannot be force-upgraded overnight.
public function toArray(Request $request): array { return [ "id" => $this->id, "title" => $this->title, "body" => $this->body, ]; }
Test the endpoints
Endpoint tests speak HTTP: send JSON, assert the status, assert the structure. One test per route catches renamed fields and broken validation long before a mobile release does.
$response = $this->getJson("/api/posts"); $response->assertOk(); $response->assertJsonStructure(["data"]); $created = $this->postJson("/api/posts", ["title" => "Hello", "body" => "World"]); $created->assertCreated();
Next: Capstone: shop cart
Article author: Arthur Isaev