如何快速上手LaravelAPI,编写首个LaravelHelloWorldAPI接口?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1068个文字,预计阅读时间需要5分钟。
新手上路,常误以为API就是高大上,直接抄文档里带版本、中间件、资源控制器的写法。结果连+404+都搞不定,要么是路由没注册,要么是中间件拦了。第一个接口只求通,不求全。
实操建议:
- 在
routes/api.php里写最简路由:Route::get('/hello', function () { return ['message' => 'Hello World']; });
- 别加
middleware('api')—— Laravel 9+ 默认已为api.php自动加载该中间件,手动加反而可能重复触发 - 别用
php artisan make:controller Api/HelloController再绑定路由,函数式写法更直白,避免控制器空壳和命名空间错位 - 访问时必须带
/api/前缀(如http://localhost:8000/api/hello),这是 Laravel 对routes/api.php的硬编码约定,不是可配选项
Response::json() 不需要显式调用,数组自动转 JSON
看到别人代码里写 return response()->json(['msg' => 'ok']),就以为“返回 JSON 必须这么写”,其实纯属冗余。Laravel 的响应自动序列化规则很明确:返回数组或 Eloquent 模型,且当前请求 Accept 头含 application/json(Postman/curl 默认带),就会走 JSON 响应流程。
常见错误现象:
- 用
return view('hello')—— 这会渲染 HTML,API 接口不能混用 Web 视图层 - 用
echo json_encode([...])+exit—— 绕过 Laravel 响应生命周期,丢失状态码、Header、中间件钩子 - 返回字符串(如
return 'hello')—— 得到的是text/html响应体,前端fetch().json()会报Unexpected token h
正确姿势就是直接 return ['message' => 'Hello World'],干净、可测、符合框架预期。
调试时别只看浏览器地址栏,重点查 419 Page Expired 和 CORS 报错
本地跑通后,用 Vue/React 调用就崩?大概率不是接口问题,而是跨域或 CSRF 检查卡住。Laravel 的 api 中间件组默认禁用 VerifyCsrfToken,但前提是请求真被识别为 API 请求 —— 关键看是否命中 routes/api.php 且路径以 /api/ 开头。
容易踩的坑:
- 前端发请求到
/hello(漏掉/api/),路由落到web.php,触发 CSRF 验证 → 返回419 Page Expired - 用 Postman 测试没问题,但浏览器里 fetch 报
No 'Access-Control-Allow-Origin' header—— 因为 Laravel 默认不给 API 加 CORS Header,需装fruitcake/laravel-cors并发布配置,否则前端跨域必失败 - 修改了
config/cors.php但没清缓存:php artisan config:clear必须执行,否则改了等于没改
测试接口别只靠浏览器,用 curl -H "Accept: application/json" 模拟真实调用
浏览器直接打开 /api/hello 看到 JSON 格式就以为 OK?其实它发的是 Accept: text/html,*/*,Laravel 会 fallback 到 JSON(因无 HTML 视图),但这掩盖了 Accept 头不匹配的真实行为。生产环境的前端、移动端、CLI 工具都严格按 Accept: application/json 发请求。
实操建议:
- 终端执行:
curl -H "Accept: application/json" http://localhost:8000/api/hello
- 观察响应头是否有
Content-Type: application/json,没有就说明框架没走 JSON 分支 - 故意传错 Accept:
curl -H "Accept: text/plain" http://localhost:8000/api/hello,应得到406 Not Acceptable—— 这才是符合 REST 规范的响应
复杂点在于:Laravel 的 JSON 自动转换只对数组和模型生效,如果返回的是字符串、数字或 null,它不会自动包装成 JSON,也不会报错,而是返回原始类型 + text/html Content-Type —— 这个细节几乎没人注意,直到前端解析失败才回头翻源码。
本文共计1068个文字,预计阅读时间需要5分钟。
新手上路,常误以为API就是高大上,直接抄文档里带版本、中间件、资源控制器的写法。结果连+404+都搞不定,要么是路由没注册,要么是中间件拦了。第一个接口只求通,不求全。
实操建议:
- 在
routes/api.php里写最简路由:Route::get('/hello', function () { return ['message' => 'Hello World']; });
- 别加
middleware('api')—— Laravel 9+ 默认已为api.php自动加载该中间件,手动加反而可能重复触发 - 别用
php artisan make:controller Api/HelloController再绑定路由,函数式写法更直白,避免控制器空壳和命名空间错位 - 访问时必须带
/api/前缀(如http://localhost:8000/api/hello),这是 Laravel 对routes/api.php的硬编码约定,不是可配选项
Response::json() 不需要显式调用,数组自动转 JSON
看到别人代码里写 return response()->json(['msg' => 'ok']),就以为“返回 JSON 必须这么写”,其实纯属冗余。Laravel 的响应自动序列化规则很明确:返回数组或 Eloquent 模型,且当前请求 Accept 头含 application/json(Postman/curl 默认带),就会走 JSON 响应流程。
常见错误现象:
- 用
return view('hello')—— 这会渲染 HTML,API 接口不能混用 Web 视图层 - 用
echo json_encode([...])+exit—— 绕过 Laravel 响应生命周期,丢失状态码、Header、中间件钩子 - 返回字符串(如
return 'hello')—— 得到的是text/html响应体,前端fetch().json()会报Unexpected token h
正确姿势就是直接 return ['message' => 'Hello World'],干净、可测、符合框架预期。
调试时别只看浏览器地址栏,重点查 419 Page Expired 和 CORS 报错
本地跑通后,用 Vue/React 调用就崩?大概率不是接口问题,而是跨域或 CSRF 检查卡住。Laravel 的 api 中间件组默认禁用 VerifyCsrfToken,但前提是请求真被识别为 API 请求 —— 关键看是否命中 routes/api.php 且路径以 /api/ 开头。
容易踩的坑:
- 前端发请求到
/hello(漏掉/api/),路由落到web.php,触发 CSRF 验证 → 返回419 Page Expired - 用 Postman 测试没问题,但浏览器里 fetch 报
No 'Access-Control-Allow-Origin' header—— 因为 Laravel 默认不给 API 加 CORS Header,需装fruitcake/laravel-cors并发布配置,否则前端跨域必失败 - 修改了
config/cors.php但没清缓存:php artisan config:clear必须执行,否则改了等于没改
测试接口别只靠浏览器,用 curl -H "Accept: application/json" 模拟真实调用
浏览器直接打开 /api/hello 看到 JSON 格式就以为 OK?其实它发的是 Accept: text/html,*/*,Laravel 会 fallback 到 JSON(因无 HTML 视图),但这掩盖了 Accept 头不匹配的真实行为。生产环境的前端、移动端、CLI 工具都严格按 Accept: application/json 发请求。
实操建议:
- 终端执行:
curl -H "Accept: application/json" http://localhost:8000/api/hello
- 观察响应头是否有
Content-Type: application/json,没有就说明框架没走 JSON 分支 - 故意传错 Accept:
curl -H "Accept: text/plain" http://localhost:8000/api/hello,应得到406 Not Acceptable—— 这才是符合 REST 规范的响应
复杂点在于:Laravel 的 JSON 自动转换只对数组和模型生效,如果返回的是字符串、数字或 null,它不会自动包装成 JSON,也不会报错,而是返回原始类型 + text/html Content-Type —— 这个细节几乎没人注意,直到前端解析失败才回头翻源码。

