游客发表
去年帮朋友调一个库存同步接口,实例对方工程师发来的教程文档里写着“请调用 WebAPI 获取实时库存”。他问我:WebAPI 到底是实例个啥?是不是就是 HTTP 接口?我说,差不多,教程但这个词本身没那么神秘,实例它就是教程一个“能被程序调用的函数”,只不过调用方式走的实例是网络协议。
先看一个最小可运行的教程例子。假设你有一个 ASP.NET Core 项目,实例在 Program.cs 里加这么几行:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/hello",教程 () => "Hello WebAPI"); app.Run(); 跑起来,浏览器访问 http://localhost:5000/hello,实例页面上会出现一行字。教程这就是实例一个 WebAPI——没有页面、没有按钮,教程返回的实例是纯文本。前端用 fetch('/hello') 就能拿到这个字符串,然后决定把它塞到哪个 DOM 节点里。
实际项目里不会只返回一个字符串。拿订单查询来说,通常要返回 JSON。把上面的代码改成:
app.MapGet("/orders/{ id}", (int id) => { var order = new { Id = id, Product = "键盘", Quantity = 2, Status = "已发货" }; return Results.Ok(order); }); 访问 /orders/1001,得到 { "id":1001,"product":"键盘","quantity":2,"status":"已发货"}。注意 { id} 是路由参数,int id 会自动从 URL 里解析。如果传个 /orders/abc,框架直接返回 400,连你的代码都不会进。这个细节我踩过坑——早期写接口时自己手动解析字符串,结果类型转换异常把整个请求搞崩了。
POST 请求稍微不一样。前端提交表单或 JSON 体,后端用 [FromBody] 接。比如创建一个新订单:
app.MapPost("/orders", (Order order) => { // 这里通常写数据库插入 return Results.Created($"/orders/{ order.Id}", order); }); 对应的 Order 类需要公开属性,不然模型绑定拿不到值。我见过有人把字段写成私有的,调试半天说“参数怎么都是 null”。这不是框架的锅,是 C# 属性反射的基本规则。
状态码别乱用。200 表示成功,201 表示创建成功,400 是客户端参数错误,404 是资源不存在,500 是服务端自己炸了。有一次对接第三方,对方所有错误都返回 200,然后在 body 里塞 { "code":500}。这种设计让调用方很难受——HTTP 层看不出问题,必须解析完 body 才知道成败。能改就改,不能改就在客户端封装一层判断。
认证方面,最简单的方案是加一个请求头。比如 Authorization: Bearer xxxxx,后端用中间件校验。别把密钥直接写在 URL 里,日志一打全泄露。我见过把 token 拼在 query string 里的接口,服务器访问日志明文记录,等于把钥匙挂在门上。
调试工具用 curl 或者 Postman 都行。curl 更直接:
curl -X POST http://localhost:5000/orders \ -H "Content-Type: application/json" \ -d '{ "id":1002,"product":"鼠标","quantity":1}' 返回 201 和刚提交的 JSON,说明链路通了。如果返回 415,检查 Content-Type;返回 400,检查 JSON 格式和字段类型。这些错误信息比“接口不通”有用得多。
WebAPI 本身不复杂,复杂的是业务逻辑、错误处理和版本管理。一个接口从 /api/v1/orders 改到 /api/v2/orders,老客户端还得继续用 v1,这时候路由要同时保留两套。我一般建议新项目一开始就带版本号,省得后面拆得头疼。
最后说个观察:很多教程把 WebAPI 讲成“RESTful 架构风格”,然后列一堆原则。实际写代码时,先跑通一个 GET 和一个 POST,比背概念有用。接口能返回正确数据、能处理异常、能通过认证,就已经合格了。剩下的 HATEOAS、超媒体那些,等业务真需要再说。
友情链接