如何在Laravel中创建RESTful API

直接答案是:在laravel中构建restful api需要通过定义路由、创建控制器、使用api资源进行数据转换,并结合sanctum实现认证与授权。1. 定义api路由时,将所有api相关路由集中放在routes/api.php文件中,并使用route::apiresource()生成标准crud路由,同时为版本管理添加前缀如v1;2. 创建api控制器时,使用php artisan make:controller –api生成仅包含必要方法的控制器,并实现index、store、show、update和destroy等操作;3. 使用api资源类(如通过php artisan make:resource生成)来控制模型序列化格式,统一返回结构并优化关联数据加载;4. 在认证方面,使用laravel sanctum提供轻量级api令牌认证,在用户模型引入hasapitokens trait,并通过createtoken()生成令牌;5. 授权方面,使用策略(policy)封装特定模型的访问控制逻辑,并在控制器中调用$this->authorize()进行权限验证;6. 统一响应格式与状态码,如成功时返回200、201或204,错误时根据情况返回400、401、403、404、422或500等,并在响应体中包含清晰的信息结构。

如何在Laravel中创建RESTful API

如果你问我如何在Laravel里搞一个RESTful API,我的直接答案是:它其实就是一套约定俗成的规矩,加上Laravel本身提供的那些趁手的工具,比如路由、控制器、Eloquent ORM,以及非常实用的API资源和Sanctum认证。核心在于把你的业务逻辑抽象成一个个资源,然后通过HTTP动词去操作它们。说实话,刚开始接触API的时候,我也曾被那些HTTP动词和状态码搞得有点晕,但一旦你理解了RESTful的核心思想——资源导向,一切就豁然开朗了。

解决方案

在Laravel中创建RESTful API,通常我会这样一步步来:

定义API路由:所有API相关的路由都放在routes/api.php文件里。Laravel提供了一个非常方便的Route::apiResource方法,它能自动为你的资源生成标准的CRUD(创建、读取、更新、删除)路由。

// routes/api.phpuse AppHttpControllersApiV1PostController;use IlluminateSupportFacadesRoute;Route::prefix('v1')->group(function () {    Route::apiResource('posts', PostController::class);    // 如果需要,还可以定义一些非标准的动作    Route::post('posts/{post}/publish', [PostController::class, 'publish']);});

这里我加了个v1前缀,因为API版本管理是个好习惯,未来升级时能少踩很多坑。

创建API控制器:使用Artisan命令可以快速生成一个API控制器。--api标志会生成一个不包含createedit方法的控制器,这符合API的无状态特性。

php artisan make:controller Api/V1/PostController --api

在控制器里,你需要实现index(获取列表)、store(创建)、show(获取详情)、update(更新)和destroy(删除)等方法。

// app/Http/Controllers/Api/V1/PostController.phpnamespace AppHttpControllersApiV1;use AppHttpControllersController;use AppHttpResourcesPostResource; // 稍后会创建use AppModelsPost;use IlluminateHttpRequest;use IlluminateValidationValidationException;class PostController extends Controller{    public function index()    {        $posts = Post::latest()->paginate(10);        return PostResource::collection($posts); // 使用资源集合返回    }    public function store(Request $request)    {        try {            $validatedData = $request->validate([                'title' => 'required|string|max:255',                'content' => 'required|string',                // ... 其他验证规则            ]);            $post = Post::create($validatedData);            return new PostResource($post); // 返回新创建的资源        } catch (ValidationException $e) {            return response()->json([                'message' => 'Validation Failed',                'errors' => $e->errors()            ], 422);        }    }    public function show(Post $post)    {        return new PostResource($post);    }    public function update(Request $request, Post $post)    {        try {            $validatedData = $request->validate([                'title' => 'sometimes|string|max:255',                'content' => 'sometimes|string',            ]);            $post->update($validatedData);            return new PostResource($post);        } catch (ValidationException $e) {            return response()->json([                'message' => 'Validation Failed',                'errors' => $e->errors()            ], 422);        }    }    public function destroy(Post $post)    {        $post->delete();        return response()->json(null, 204); // 204 No Content,表示成功删除    }    public function publish(Post $post)    {        $post->update(['published_at' => now()]);        return new PostResource($post);    }}

创建API资源:这是我个人在使用Laravel构建API时,最喜欢的一点。API资源允许你轻松地将模型转换为JSON格式,并且可以控制哪些属性应该被包含,甚至可以添加自定义属性。

php artisan make:resource PostResource
// app/Http/Resources/PostResource.phpnamespace AppHttpResources;use IlluminateHttpResourcesJsonJsonResource;class PostResource extends JsonResource{    public function toArray($request)    {        return [            'id' => $this->id,            'title' => $this->title,            'content' => $this->content,            'slug' => $this->slug,            'created_at' => $this->created_at->format('Y-m-d H:i:s'),            'updated_at' => $this->updated_at->format('Y-m-d H:i:s'),            // 你可以根据需要添加关联数据,比如作者信息            // 'author' => new UserResource($this->whenLoaded('user')),        ];    }}

认证与授权:对于API,Laravel Sanctum是一个非常棒的选择,尤其适合单页面应用(SPA)和移动应用。它提供了一种轻量级的API令牌认证系统。

composer require laravel/sanctumphp artisan vendor:publish --tag=sanctum-configphp artisan migrate

然后在你的User模型中引入HasApiTokens trait。

// app/Models/User.phpuse LaravelSanctumHasApiTokens;class User extends Authenticatable{    use HasApiTokens, Notifiable;    // ...}

这样,用户登录后就可以生成API令牌,客户端使用这个令牌进行后续请求。

如何设计一个清晰、可维护的Laravel API路由结构?

设计API路由结构,在我看来,最重要的是“一致性”和“可预测性”。当你的API变得庞大时,一个混乱的路由会让开发者抓狂。

首先,版本化是必须的。我通常会把API版本放在URL路径中,比如/api/v1/posts。这样当你的API需要进行重大更新时,可以发布/api/v2/posts,而不会影响到使用旧版本API的客户端。Laravel的Route::prefix('v1')或者Route::group(['prefix' => 'v1'])可以很好地实现这一点。

其次,资源化命名是RESTful的核心。URL应该代表资源,而不是操作。例如,获取所有文章是/posts,获取单篇文章是/posts/{id}。操作通过HTTP动词(GET, POST, PUT/PATCH, DELETE)来区分。Laravel的Route::apiResource('posts', PostController::class)就是这一思想的完美体现,它会自动帮你生成一套标准的资源路由。如果你有嵌套资源,比如获取某篇文章的所有评论,可以考虑/posts/{post}/comments

再者,命名空间和分组能让你的路由文件更整洁。把API控制器放在AppHttpControllersApiV1这样的命名空间下,并在路由文件中使用Route::namespace('ApiV1')->group(...)或者直接在apiResource里指定完整的控制器路径,能有效避免命名冲突,也让文件结构一目了然。

最后,对于那些不完全符合RESTful规范的“自定义”操作,比如文章发布,我倾向于将其作为资源的子路由,或者使用一个明确的动词,例如POST /posts/{post}/publish。这比使用GET /posts/publish/{post_id}要好得多,因为它更明确地表示这是一个对特定文章的“动作”。

在Laravel API中如何处理数据转换和响应格式?

数据转换和响应格式是API的“面子工程”,直接影响到客户端的开发体验。Laravel在这方面提供了非常强大的工具,那就是API资源(API Resources)

阿里妈妈·创意中心 阿里妈妈·创意中心

阿里妈妈营销创意中心

阿里妈妈·创意中心 0 查看详情 阿里妈妈·创意中心

我个人觉得,API资源是Laravel在API开发方面最亮眼的功能之一。它解决了两个核心问题:

数据过滤:你可能不想把数据库里所有的字段都暴露给客户端,比如用户的密码哈希值。API资源让你精确控制哪些字段应该被序列化。数据整形:有时候,数据库字段名可能不符合API的命名规范(比如snake_case vs camelCase),或者你需要对数据进行一些计算或格式化(比如日期格式)。资源允许你自定义这些。

使用php artisan make:resource YourResource创建一个资源类后,你可以在toArray方法里定义返回的数据结构。对于单个模型,使用new YourResource($model);对于模型集合或分页结果,使用YourResource::collection($collection)

// 假设有一个 UserResourcepublic function toArray($request){    return [        'id' => $this->id,        'name' => $this->name,        'email' => $this->email,        'profile_url' => url('/users/' . $this->id), // 可以添加计算属性        'posts_count' => $this->whenLoaded('posts', fn() => $this->posts->count()), // 条件加载关联数据    ];}

whenLoaded方法特别有用,它只会在关联关系已经被加载时才包含该数据,避免了N+1查询问题。

统一的响应格式也至关重要。我通常会约定一个标准的JSON响应结构,尤其是在处理错误时。例如,成功响应可能直接返回数据,而错误响应则包含messageerrors(如果涉及验证失败)和code(HTTP状态码)等字段。

// 成功响应{    "data": {        "id": 1,        "title": "我的第一篇文章"        // ...    }}// 验证失败响应{    "message": "The given data was invalid.",    "errors": {        "title": [            "标题不能为空。"        ],        "content": [            "内容必须至少包含10个字符。"        ]    }}// 其他错误响应{    "message": "资源未找到。",    "code": 404}

在控制器中,你可以使用response()->json(...)来构建这些响应。HTTP状态码的正确使用也同样重要,比如200 OK、201 Created、204 No Content、400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found、422 Unprocessable Entity、500 Internal Server Error等。

Laravel API的认证与授权有哪些推荐实践?

API的认证和授权,在我看来,是确保数据安全的关键环节。Laravel提供了几种方式,但对于API,我最推荐的是Laravel Sanctum

认证 (Authentication):Sanctum是一个轻量级的API认证系统,它支持两种主要的使用场景:

SPA认证:对于单页面应用,Sanctum通过基于Cookie的会话认证来提供无缝的用户体验。它会为你处理CSRF保护和会话管理,让前端可以像传统Web应用一样直接调用API。API令牌认证:这是最常见的API认证方式,适用于移动应用、第三方服务或者需要无状态认证的场景。用户登录后,你可以为他们生成一个API令牌(Personal Access Token),客户端将这个令牌放在HTTP请求的Authorization头(Bearer Token)中发送给服务器。

在用户模型上使用HasApiTokens trait后,你可以通过$user->createToken('token-name')来生成令牌,并通过$request->user('sanctum')来获取当前认证的用户。

// 登录并生成令牌示例use IlluminateHttpRequest;use IlluminateSupportFacadesAuth;public function login(Request $request){    if (!Auth::attempt($request->only('email', 'password'))) {        return response()->json(['message' => 'Invalid credentials'], 401);    }    $user = Auth::user();    $token = $user->createToken('auth_token')->plainTextToken; // 生成令牌    return response()->json([        'message' => 'Login successful',        'access_token' => $token,        'token_type' => 'Bearer',    ]);}// 保护API路由Route::middleware('auth:sanctum')->group(function () {    Route::get('/user', function (Request $request) {        return $request->user();    });});

授权 (Authorization):认证是“你是谁”,授权是“你能做什么”。Laravel的授权机制包括Gates(门禁)Policies(策略)。对于复杂的资源操作,我更倾向于使用策略,因为它能将特定模型的授权逻辑封装在一个类中,让代码更清晰、更易于维护。

例如,你可以为Post模型创建一个策略:

php artisan make:policy PostPolicy --model=Post
// app/Policies/PostPolicy.phpnamespace AppPolicies;use AppModelsUser;use AppModelsPost;use IlluminateAuthAccessHandlesAuthorization;class PostPolicy{    use HandlesAuthorization;    public function view(User $user, Post $post)    {        return true; // 任何人都可以查看文章    }    public function update(User $user, Post $post)    {        return $user->id === $post->user_id; // 只有文章作者才能更新    }    public function delete(User $user, Post $post)    {        return $user->id === $post->user_id; // 只有文章作者才能删除    }}

然后在AuthServiceProvider中注册策略:

// app/Providers/AuthServiceProvider.phpprotected $policies = [    Post::class => PostPolicy::class,];

最后,在控制器中使用$this->authorize()方法进行授权检查:

// app/Http/Controllers/Api/V1/PostController.phppublic function update(Request $request, Post $post){    $this->authorize('update', $post); // 检查当前用户是否有权更新此文章    // ... 更新逻辑}public function destroy(Post $post){    $this->authorize('delete', $post); // 检查当前用户是否有权删除此文章    // ... 删除逻辑}

如果授权失败,Laravel会自动抛出一个AuthorizationException,并返回403 Forbidden响应,这非常符合API的规范。通过结合Sanctum进行认证,再配合策略进行授权,你的Laravel API就能构建起一套强大而安全的访问控制体系。

以上就是如何在Laravel中创建RESTful API的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/581636.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
vscode怎么全局搜索构建输出_vscode在构建输出日志中全局搜索的技巧
上一篇 2025年11月10日 11:12:16
《扇贝单词》设置用户名方法
下一篇 2025年11月10日 11:12:24

相关推荐

  • composer require-dev和require有什么不同_Composer Require与Require-Dev区别解析

    require用于声明项目运行必需的依赖,如框架、数据库组件和第三方SDK,这些包会随项目部署到生产环境;2. require-dev用于声明仅在开发和测试阶段需要的工具,如PHPUnit、PHPStan、Faker等,不会默认部署到生产环境;3. 安装时composer install根据环境决定…

    2026年5月10日
    1000
  • 开源免费PHP工具 PHP开发效率提升利器

    推荐开源免费PHP开发工具以提升效率:VS Code、Sublime Text轻量高效,PhpStorm专业强大;调试用Xdebug、Kint、Ray;依赖管理选Composer;代码质量工具包括PHPStan、Psalm、PHP_CodeSniffer;数据库管理可用%ignore_a_1%MyA…

    2026年5月10日
    000
  • Matplotlib 地图中多类型图例的创建与优化

    Matplotlib 地图中多类型图例的创建与优化Matplotlib 地图中多类型图例的创建与优化Matplotlib 地图中多类型图例的创建与优化Matplotlib 地图中多类型图例的创建与优化

    本教程旨在解决matplotlib地图可视化中,如何在一个图例中同时展示颜色块(如区域分类)和自定义标记(如特定兴趣点)的问题。文章详细介绍了当传统`patch`对象无法正确显示标记时,如何利用`matplotlib.lines.line2d`创建标记图例句柄,并将其与颜色块图例句柄合并,从而生成一…

    2026年5月10日 用户投稿
    100
  • Golang JSON序列化:控制敏感字段暴露的最佳实践

    本教程探讨golang中如何高效控制结构体字段在json序列化时的可见性。当需要将包含敏感信息的结构体数组转换为json响应时,通过利用`encoding/json`包提供的结构体标签,特别是`json:”-“`,可以轻松实现对特定字段的忽略,从而避免敏感数据泄露,确保api…

    2026年5月10日
    000
  • 利用海象运算符简化条件赋值:Python教程与最佳实践

    本文旨在探讨Python中海象运算符(:=)在条件赋值场景下的应用。通过对比传统if/else语句与海象运算符,以及条件表达式,分析海象运算符在简化代码、提高可读性方面的优势与局限性。并通过具体示例,展示如何在列表推导式等场景下合理使用海象运算符,同时强调其潜在的复杂性及替代方案,帮助开发者更好地掌…

    2026年5月10日
    100
  • Debian syslog性能优化技巧有哪些

    提升Debian系统syslog (通常基于rsyslog)性能,关键在于精简配置和高效处理日志。以下策略能有效优化日志管理,提升系统整体性能: 精简配置,高效加载: 在rsyslog配置文件中,仅加载必要的输入、输出和解析模块。 使用全局指令设置日志级别和格式,避免不必要的处理。 自定义模板: 创…

    2026年5月10日
    000
  • 比特币新手教程 比特币交易平台有哪些

    比特币是一种去中心化的数字货币,基于区块链技术实现点对点交易,具有匿名性、有限发行和不可篡改等特点;新手可通过交易所购买,P2P交易获得比特币,常用平台包括Binance、OKX和Huobi;交易流程包括注册账户、实名认证、绑定支付方式、充值法币并下单购买,可选择市价单或限价单;比特币存储方式有交易…

    2026年5月10日
    000
  • c++中的SFINAE技术是什么_c++模板编程中的SFINAE原理与应用

    SFINAE 是“替换失败不是错误”的原则,指模板实例化时若参数替换导致错误,只要存在其他合法候选,编译器不报错而是继续重载决议。它用于条件启用模板、类型检测等场景,如通过 decltype 或 enable_if 控制函数重载,实现类型特征判断。尽管 C++20 引入 Concepts 简化了部分…

    2026年5月10日
    000
  • Go语言mgo查询构建:深入理解bson.M与日期范围查询的正确实践

    本文旨在解决go语言mgo库中构建复杂查询时,特别是涉及嵌套`bson.m`和日期范围筛选的常见错误。我们将深入剖析`bson.m`的类型特性,解释为何直接索引`interface{}`会导致“invalid operation”错误,并提供一种推荐的、结构清晰的代码重构方案,以确保查询条件能够正确…

    2026年5月10日
    100
  • RichHandler与Rich Progress集成:解决显示冲突的教程

    在使用rich库的`richhandler`进行日志输出并同时使用`progress`组件时,可能会遇到显示错乱或溢出问题。这通常是由于为`richhandler`和`progress`分别创建了独立的`console`实例导致的。解决方案是确保日志处理器和进度条组件共享同一个`console`实例…

    2026年5月10日
    000
  • Golang goroutine与channel调试技巧

    使用go run -race检测数据竞争,结合runtime.NumGoroutine监控协程数量,通过pprof分析阻塞调用栈,利用select超时避免永久阻塞,有效排查goroutine泄漏、死锁和数据竞争问题。 Go语言的goroutine和channel是并发编程的核心,但它们也带来了调试上…

    2026年5月10日
    000
  • 使用 Jupyter Notebook 进行探索性数据分析

    Jupyter Notebook通过单元格实现代码与Markdown结合,支持数据导入(pandas)、清洗(fillna)、探索(matplotlib/seaborn可视化)、统计分析(describe/corr)和特征工程,便于记录与分享分析过程。 Jupyter Notebook 是进行探索性…

    2026年5月10日
    000
  • 《魔兽世界》将于6月11日开启国服回归技术测试

    《魔兽世界》将于6月11日开启国服回归技术测试《魔兽世界》将于6月11日开启国服回归技术测试《魔兽世界》将于6月11日开启国服回归技术测试《魔兽世界》将于6月11日开启国服回归技术测试

    《%ign%ignore_a_1%re_a_1%》官方宣布,将于6月11日开启国服回归技术测试,时间为7天,并称可以在6月内正式开服,玩家们可以访问官网下载战网客户端并预下载“巫妖王之怒”客户端,技术测试详情见下图。 WordAi WordAI是一个AI驱动的内容重写平台 53 查看详情 以上就是《…

    2026年5月10日 用户投稿
    200
  • 如何在HTML中插入表单元素_HTML表单控件与输入类型使用指南

    HTML表单通过标签构建,包含action和method属性定义数据提交目标与方式,常用input类型如text、password、email等适配不同输入需求,配合label、required、placeholder提升可用性,结合textarea、select、button等控件实现完整交互,是…

    2026年5月10日
    100
  • 网站标题关键词更新后,搜索引擎为何仍显示旧标题?

    网站标题更新后,搜索引擎为何显示旧标题? 网站SEO优化中,站长常修改网站标题关键词,期望搜索结果显示自定义标题。然而,即使更新标签、meta keywords、meta description和结构化数据中的name属性后,搜索结果仍显示旧标题,这令人费解。本文将对此进行解释。 问题:站长修改了网…

    2026年5月10日
    100
  • 创建指定大小并填充特定数据的Golang文件教程

    本文将介绍如何使用Golang创建一个指定大小的文件,并用特定数据填充它。我们将使用 `os` 包提供的函数来创建和截断文件,从而实现快速生成大文件的目的。示例代码展示了如何创建一个10MB的文件,并将其填充为全零数据。掌握这些方法,可以方便地在例如日志系统或磁盘队列等场景中,预先创建测试文件或初始…

    2026年5月10日
    000
  • Python命令怎样使用profile分析脚本性能 Python命令性能分析的基础教程

    使用Python的cProfile模块分析脚本性能最直接的方式是通过命令行执行python -m cProfile your_script.py,它会输出每个函数的调用次数、总耗时、累积耗时等关键指标,帮助定位性能瓶颈;为进一步分析,可将结果保存为文件python -m cProfile -o ou…

    2026年5月10日
    000
  • 使用 WebCodecs VideoDecoder 实现精确逐帧回退

    本文档旨在解决在使用 WebCodecs VideoDecoder 进行视频解码时,实现精确逐帧回退的问题。通过比较帧的时间戳与目标帧的时间戳,可以避免渲染中间帧,从而提高用户体验。本文将提供详细的解决方案和示例代码,帮助开发者实现精确的视频帧控制。 在使用 WebCodecs VideoDecod…

    2026年5月10日
    000
  • 如何插入查询结果数据_SQL插入Select查询结果方法

    如何插入查询结果数据_SQL插入Select查询结果方法如何插入查询结果数据_SQL插入Select查询结果方法如何插入查询结果数据_SQL插入Select查询结果方法如何插入查询结果数据_SQL插入Select查询结果方法

    使用INSERT INTO…SELECT语句可高效插入数据,通过NOT EXISTS、LEFT JOIN、MERGE语句或唯一约束避免重复;表结构不一致时可通过别名、类型转换、默认值或计算字段处理;结合存储过程可提升可维护性,支持参数化与动态SQL。 将查询结果数据插入到另一个表中,可以…

    2026年5月10日 用户投稿
    000
  • Debian Copilot的社区活跃度如何

    debian copilot是codeberg社区维护的ai助手,旨在为debian用户提供服务。尽管搜索结果中没有直接提供关于debian copilot社区支持活跃度的具体数据,但我们可以通过debian社区的整体活跃度和特点来推断其活跃性。 Debian社区的一般情况: Debian拥有详尽的…

    2026年5月10日
    000

发表回复

登录后才能评论
关注微信