学习 Laravel API:从问题到解决方案!

发布: (2026年1月11日 GMT+8 22:24)
8 min read
原文: Dev.to

I’m happy to translate the article for you, but I need the actual text of the article (the content you’d like translated). Could you please paste the article’s body here? I’ll keep the source line and all formatting exactly as you requested.

为什么 API 很重要?

  • API 是 frontendbackend 之间的桥梁。
  • 单页应用 (SPA)移动应用 必不可少。
  • 没有 API,数据无法展示给用户。

Laravel 示例 API:文章 CRUD

在本文中,我们将使用 Laravel 创建 文章 API(CRUD)。简洁但非常适用于博客、新闻或练习项目。

Laravel API 工作流程

在编写代码之前,先了解流程:

Client (Postman / Frontend)
   → Request HTTP
   → Route API
   → Controller
   → Model
   → Database
   → Response JSON

每当客户端请求数据时,请求会经过路由,由控制器处理,从模型/数据库获取数据,然后返回 JSON 响应。

第一步:设置 Laravel 项目

  • 最新的 Laravel 版本(例如 10.x)
  • 确保已安装 Composer
composer create-project --prefer-dist laravel/laravel belajar-api

.env 中设置数据库

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=belajar_api
DB_USERNAME=root
DB_PASSWORD=

Step 2: 创建模型与迁移 Article

为什么使用 -m

-m 会自动创建迁移文件,因此无需手动创建。

php artisan make:model Article -m

编辑迁移

打开文件 database/migrations/..._create_articles_table.php 并将 up() 方法改为:

public function up()
{
    Schema::create('articles', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}

运行迁移

php artisan migrate

$fillable 的重要性

在模型文件 app/Models/Article.php 中添加:

protected $fillable = ['title', 'content'];

为什么必须填写?
如果不填写,Laravel 因为 mass assignment 保护而无法保存数据。这是一个安全特性,确保只有被允许的列可以被插入或更新。

第 3 步:创建文章 API 控制器

创建资源控制器:

php artisan make:controller Api/ArticleController --resource

主要功能说明

方法功能
index()获取所有文章,返回 JSON 格式
store()保存新文章(验证 → 创建)
show($id)根据 ID 获取文章详情
update($id)更新指定文章的数据
destroy($id)删除文章

示例实现(简要)

public function store(Request $request)
{
    $validated = $request->validate([
        'title'   => 'required',
        'content' => 'required',
    ]);

    $article = Article::create($validated);
    return response()->json($article, 201);
}

public function show($id)
{
    return Article::findOrFail($id);
}

public function update(Request $request, $id)
{
    $article = Article::findOrFail($id);
    $article->update($request->all());
    return response()->json($article);
}

public function destroy($id)
{
    Article::destroy($id);
    return response()->json(null, 204);
}

Source:

第4步:添加 API 路由

编辑文件 routes/api.php

use App\Http\Controllers\Api\ArticleController;

Route::apiResource('articles', ArticleController::class);

使用 Postman(或 cURL)测试 API 的方法

方法端点功能请求体示例响应示例
GET/api/articles列出所有文章[{...}]
POST/api/articles保存新文章{ "title": "Belajar Laravel API", "content": "Tutorial lengkap & mudah!" }{ "id": 1, ... }
GET/api/articles/{id}文章详情{ "id": 1, ... }
PUT/api/articles/{id}更新文章{ "title": "Update", "content": "Edit konten" }{ "id": 1, ... }
DELETE/api/articles/{id}删除文章null

完整示例 请求 与 响应

请求 POST

POST /api/articles HTTP/1.1
Content-Type: application/json

{
    "title": "Belajar Laravel API",
    "content": "Tutorial lengkap & mudah!"
}

响应 201 Created

{
    "id": 1,
    "title": "Belajar Laravel API",
    "content": "Tutorial lengkap & mudah!",
    "created_at": "2026-01-10T12:34:56.000000Z",
    "updated_at": "2026-01-10T12:34:56.000000Z"
}

请求 GET

GET /api/articles/1 HTTP/1.1

响应 200 OK

{
    "id": 1,
    "title": "Belajar Laravel API",
    "content": "Tutorial lengkap & mudah!",
    "created_at": "2026-01-10T12:34:56.000000Z",
    "updated_at": "2026-01-10T12:34:56.000000Z"
}

请求 PUT

PUT /api/articles/1 HTTP/1.1
Content-Type: application/json

{
    "title": "Update Judul",
    "content": "Konten sudah diupdate!"
}

响应 200 OK

{
    "id": 1,
    "title": "Update Judul",
    "content": "Konten sudah diupdate!",
    "created_at": "2026-01-10T12:34:56.000000Z",
    "updated_at": "2026-01-11T08:15:30.000000Z"
}

请求 DELETE

DELETE /api/articles/1 HTTP/1.1

响应 204 No Content

未返回任何内容。

结束语

通过遵循上述步骤,你已经拥有完整的 API Laravel 用于文章的 CRUD 操作。现在前端 React(或其他应用)可以毫无问题地与后端通信——再也不会在 Postman 中“转来转去”了!祝你尝试顺利,取得成功。 🚀

API Laravel CRUD 示例

请求与响应示例

获取所有文章

请求

GET /api/articles

响应 200 OK

[
    {
        "id": 1,
        "title": "First Article",
        "content": "Lorem ipsum..."
    },
    {
        "id": 2,
        "title": "Second Article",
        "content": "Dolor sit amet..."
    }
]

获取单篇文章

请求

GET /api/articles/1

响应 200 OK

{
    "id": 1,
    "title": "First Article",
    "content": "Lorem ipsum..."
}

创建文章(POST)

请求

POST /api/articles
Content-Type: application/json

{
    "title": "New Article",
    "content": "Content here..."
}

响应 201 Created

{
    "id": 3,
    "title": "New Article",
    "content": "Content here..."
}

更新文章(PUT)

请求

PUT /api/articles/1
Content-Type: application/json

{
    "title": "Updated Title",
    "content": "Updated content..."
}

响应 200 OK

{
    "id": 1,
    "title": "Updated Title",
    "content": "Updated content..."
}

删除文章(DELETE)

请求

DELETE /api/articles/1

响应 204 No Content

null

错误处理与状态码(Laravel)

Laravel 会自动返回适当的 HTTP 状态码:

状态码含义
200 OK数据检索/更新成功
201 Created数据创建成功
204 No Content数据删除成功
404 Not Found未找到资源
422 Unprocessable Entity验证失败
500 Internal Server Error服务器错误

错误响应示例

{
    "message": "No query results for model [App\\Models\\Article] 99"
}

Tip: 使用控制器中的 findOrFail() 可在模型未找到时自动返回 404

常见初学者错误

  • 忘记在模型中添加 $fillable(或 $guarded),导致 mass‑assignment 错误。
  • 使用 GET 而不是 POST 来创建资源。
  • 跳过输入验证,导致脏数据。
  • 未对所有列进行过滤就直接暴露(未使用 API Resources)。
  • .env 文件配置错误(数据库凭证、端口等)。
  • 将 API 路由放在 web.php 而不是 api.php
  • 更改配置文件后未重启服务器。

提示:
• 始终检查响应中的错误信息。
• 确认 HTTP 方法和字段名称正确。
• 再次检查您的环境配置。

下一步:提升您的 API

不要止步于基础的 CRUD——探索以下 Laravel 功能:

  • Laravel Sanctum / Passport – 通过身份验证保护 API。
  • API Resources – 整洁地转换和格式化 JSON 响应。
  • Pagination – 高效处理大型数据集。
  • Rate Limiting – 防止 API 被滥用。

敬请期待后续文章,深入探讨这些主题!

🚀 让我们讨论并分享!

如果你在任何步骤卡住了,请在下方留下评论。分享你的 Laravel API 经验,或建议下篇文章的主题(例如:认证、资源、分页)。

别忘了 关注分享 本文给其他学习者!

文章结构概览

  1. 常见的初学者问题
  2. 我们将构建的内容
  3. Laravel API 工作流
  4. 快速设置
  5. 步骤式 CRUD API
  6. API 测试
  7. 常见错误
  8. 高级增强

参考资料

Back to Blog

相关文章

阅读更多 »

REST API 与常用 HTTP 方法

REST API 无处不在——从 Web 应用到移动应用以及微服务。如果你正在学习后端或前端开发,理解 REST API 和 HTTP …

当 CRUD 表格不再足够时

![《When CRUD Tables Are No Longer Enough》的封面图片](https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/ht...)