资讯专栏INFORMATION COLUMN

前后端完全分离之 API 设计

gitmilk / 2293人阅读

摘要:删除后指定产品不存在获取商品列表未分页获取全部商品成功系列的表壳材料为轻巧的银色及深空灰色阳极氧化铝金属,强化玻璃材质为显示屏提供保护。外观设计不再棱角分明,表层玻璃边有一个弧度向下延伸,与阳极氧化铝金属机身边框衔接。

背景

API 就是开发者使用的界面。我的目标不仅是能用,而且好用,跨平台(PC, Android, IOS, etc...)使用。本文将详细介绍 API 的设计及异常处理,并将异常信息进行封装友好地反馈给前端.

上篇文章 前后端完全分离初探 只是讲了些宽泛的概念,接下来的文章将直接上干货,干货的源码会挂在 GitHub 上。

前后端完全分离后,前端和后端如何交互?答:通过双方协商好的API。

接下来我分享我自己设计的 API 接口,欢迎各位朋友指教。

API 设计理念

将涉及的实体抽象成资源,即按 id 访问资源,在 url 上做文章,以后再也不用为 url 起名字而苦恼了;

使用 HTTP 动词对资源进行 CRUD(增删改查):

get -> 查, post -> 增, put -> 改, delete -> 删

URL 命名规则,对于资源无法使用一个单数名词表示的情况,我使用中横线 - 连接

资源采用名词命名,e.g:产品 -> product

新增资源,e.g:新增产品 url -> /product, verb -> POST

修改资源,e.g:修改产品 url -> /products/{id}, verb -> PUT

资源详情,e.g:指定产品详情 url -> /products/{id}, verb -> GET

删除资源,e.g:删除产品 url -> /products/{id}, verb -> DELETE

资源列表,e.g:产品列表 url -> /products, verb -> GET

资源关联关系,e.g:收藏产品 url -> /products/{id}/star, verb -> PUT

资源关联关系,e.g:删除收藏产品 url -> /products/{id}/star, verb -> DELETE

目前我 API 的设计只涉及这两点,至于第三点 HATEOAS(Hypermedia As The Engine Of Application State) 那就由读者自己去选择了,

项目地址

本文中只涉及了设计的理念,具体的实现请下载源码 rest-api,项目内写了比较详细的注释。

项目实战

实战将从业务场景出发,详细介绍如何使用 HTTP verb 对资源进行操作(状态转移),使用 JSON 返回结果(资源表述),并定义 JSON 的基础结构。

JSON 结构

requestParams:

{
}

responseBody:

{
  "meta": {
  },
  "data": {
  }
}

meta 中封装操作成功或失败的消息,data 中封装返回的具体数据。

当新建商品或更新产品时,相关属性封装在 JSON 中,通过 POST 或 PUT 发送。

{
  "name": "Apple Watch SPORT",
  "description": "Sport 系列的表壳材料为轻巧的银色及深空灰色阳极氧化铝金属,强化 Ion-X 玻璃材质为显示屏提供保护。搭配高性能 Fluoroelastomer 表带,共有 5 款缤纷色彩。"
}

当用户对商品进行操作后,将得到响应结果。GET, POST, PUT 操作成功,返回如下结果

{
  "meta": {
    "code": 201,
    "message": "创建成功"
  },
  "data": {
    "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9",
    "name": "Apple Watch SPORT",
    "description": "Sport 系列的表壳材料为轻巧的银色及深空灰色阳极氧化铝金属,强化 Ion-X 玻璃材质为显示屏提供保护。搭配高性能 Fluoroelastomer 表带,共有 5 款缤纷色彩。"
  }
}

DELETE 操作成功,返回如下结果

{
  "meta": {
    "code": 204,
    "message": "删除成功"
  }
}
业务场景一

电商网站的管理员对商品进行新增、编辑、删除、浏览的操作,暂时不考虑认证授权,只关注对商品的操作。

为了以后便于做分布式,所有资源 id(表主键)均采用 uuid。

新增商品

url: /api/product

method: POST

requestParams:

{
  "name": "Apple Watch SPORT",
  "description": "Sport 系列的表壳材料为轻巧的银色及深空灰色阳极氧化铝金属,强化 Ion-X 玻璃材质为显示屏提供保护。搭配高性能 Fluoroelastomer 表带,共有 5 款缤纷色彩。"
}

responseBody

{
  "meta": {
    "code": 201,
    "message": "创建成功"
  },
  "data": {
    "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9",
    "name": "Apple Watch SPORT",
    "description": "Sport 系列的表壳材料为轻巧的银色及深空灰色阳极氧化铝金属,强化 Ion-X 玻璃材质为显示屏提供保护。搭配高性能 Fluoroelastomer 表带,共有 5 款缤纷色彩。"
  }
}

编辑商品

url: /api/products/{id}

method: PUT

requestParams:

{
  "name": "iPhone 6",
  "description": "此次苹果发布会发布了iPhone 6与iPhone 6 Plus,搭载iOS 8,尺寸分别是4.7和5.5英寸。外观设计不再棱角分明,表层玻璃边有一个弧度向下延伸,与阳极氧化铝金属机身边框衔接。机身背部采用三段式设计。机身更薄,续航能力更强。"
}

responseBody

{
  "meta": {
    "code": 200,
    "message": "修改成功"
  },
  "data": {
    "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9",
    "name": "iPhone 6",
    "description": "此次苹果发布会发布了iPhone 6与iPhone 6 Plus,搭载iOS 8,尺寸分别是4.7和5.5英寸。外观设计不再棱角分明,表层玻璃边有一个弧度向下延伸,与阳极氧化铝金属机身边框衔接。机身背部采用三段式设计。机身更薄,续航能力更强。"
  }
}

删除商品

url: /api/products/{id}

method: DELETE

responseBody

{
  "meta": {
    "code": 204,
    "message": "删除成功"
  },
  "data": {}
}

获取商品详情

url: /api/products/{id}

method: GET

responseBody:

//删除前

{
  "meta": {
    "code": 200,
    "message": "查询成功"
  },
  "data": {
    "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9",
    "name": "Apple Watch SPORT",
    "description": "Sport 系列的表壳材料为轻巧的银色及深空灰色阳极氧化铝金属,强化 Ion-X 玻璃材质为显示屏提供保护。搭配高性能 Fluoroelastomer 表带,共有 5 款缤纷色彩。"
  }
}
//删除后
{
  "meta": {
    "code": 404,
    "message": "指定产品不存在"
  }
}

获取商品列表(未分页)

url: /api/products

method: GET

responseBody

{
  "meta": {
    "code": 200,
    "message": "获取全部商品成功"
  },
  "data": [
    {
      "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9",
      "name": "Apple Watch SPORT",
      "description": "Sport 系列的表壳材料为轻巧的银色及深空灰色阳极氧化铝金属,强化 Ion-X 玻璃材质为显示屏提供保护。搭配高性能 Fluoroelastomer 表带,共有 5 款缤纷色彩。"
    },
    {
      "id": "9db1992a-c342-4ff0-a2a4-aeb3dbfd93f6",
      "name": "Apple Watch SPORT",
      "description": "Sport 系列的表壳材料为轻巧的银色及深空灰色阳极氧化铝金属,强化 Ion-X 玻璃材质为显示屏提供保护。搭配高性能 Fluoroelastomer 表带,共有 5 款缤纷色彩。"
    },
    {
      "id": "4481619b-45c5-4729-9539-f93bb01f10d8",
      "name": "Apple Watch SPORT",
      "description": "Sport 系列的表壳材料为轻巧的银色及深空灰色阳极氧化铝金属,强化 Ion-X 玻璃材质为显示屏提供保护。搭配高性能 Fluoroelastomer 表带,共有 5 款缤纷色彩。"
    }
  ]
}

业务场景二

业务场景一中只涉及了单个资源的操作,但实际场景中还有些关联操作;如用户去电商网站浏览商品,并收藏了一些商品,之后又取消收藏了部分商品。

暂时不考虑用户认证授权,以后加了token后,用户信息可以从中获取。

收藏商品

url: /api/products/{id}/star

method: PUT

responseBody

{
  "meta": {
    "code": 200,
    "message": "收藏商品[5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9]成功"
  },
  "data": [
    {
      "id": "5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9",
      "name": "iPhone 6",
      "description": "此次苹果发布会发布了iPhone 6与iPhone 6 Plus,搭载iOS 8,尺寸分别是4.7和5.5英寸。外观设计不再棱角分明,表层玻璃边有一个弧度向下延伸,与阳极氧化铝金属机身边框衔接。机身背部采用三段式设计。机身更薄,续航能力更强。"
    }
  ]
}

取消收藏商品

url: /api/products/{id}/star

method: DELETE

responseBody

{
  "meta": {
    "code": 200,
    "message": "删除收藏商品[5308e9c2-a4ce-4dca-9373-cc1ffe63d5f9]成功"
  },
  "data": []
}

自定义异常和异常处理

所有自定义异常继承 RuntimeException,在业务层抛出,统一在 Controller 层进行处理。

异常分为全局异常和局部异常,例如 http method unsupported (405),unauthorized (401),accessDenied (403),not found (404) 等属于全局异常。针对对独立业务的一些异常属于局部异常,例如产品编辑出错。

异常在 Controller 中进行处理,并封装成 json 返回给前端,封装后的数据如下,相关实现见源码

{
  "meta": {
    "code": 404,
    "message": "指定产品不存在"
  }
}
{
  "meta": {
    "code": 405,
    "message": "Request method "POST" not supported"
  }
}
项目运行截图部分

本系列文章

前后端完全分离初探

前后端完全分离之API设计

前后端完全分离之安全认证与授权-上

前后端完全分离之安全认证与授权-下

前后端完全分离之前端模块化开发

前后端完全分离之前端路由系统

前后端完全分离之后端面向服务的模块化开发

原文出自 前后端完全分离之API设计,欢迎转载,转载请注明出处。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85663.html

相关文章

  • 前后完全分离 API 设计

    摘要:删除后指定产品不存在获取商品列表未分页获取全部商品成功系列的表壳材料为轻巧的银色及深空灰色阳极氧化铝金属,强化玻璃材质为显示屏提供保护。外观设计不再棱角分明,表层玻璃边有一个弧度向下延伸,与阳极氧化铝金属机身边框衔接。 背景 API 就是开发者使用的界面。我的目标不仅是能用,而且好用,跨平台(PC, Android, IOS, etc...)使用。本文将详细介绍 API 的设计及异常处...

    gaara 评论0 收藏0
  • 前后分离模式

    摘要:采用前后端分离模式可以减后台负担,加快研发效率,当然,前提是前端能做好的话。还是基础不够导致的后端是否风格很多公司采用了前后端分离模式后,后端仍然采用以往的传统风格,这是不合理的,风格的应该是前后端分离的最佳实践。 showImg(https://segmentfault.com/img/bVFC8f?w=690&h=360);早期的web开发是不分前端后端的。互联网进入Web2.0时...

    fobnn 评论0 收藏0
  • 前后分离模式

    摘要:采用前后端分离模式可以减后台负担,加快研发效率,当然,前提是前端能做好的话。还是基础不够导致的后端是否风格很多公司采用了前后端分离模式后,后端仍然采用以往的传统风格,这是不合理的,风格的应该是前后端分离的最佳实践。 showImg(https://segmentfault.com/img/bVFC8f?w=690&h=360);早期的web开发是不分前端后端的。互联网进入Web2.0时...

    DesGemini 评论0 收藏0
  • 前后分离模式

    摘要:采用前后端分离模式可以减后台负担,加快研发效率,当然,前提是前端能做好的话。还是基础不够导致的后端是否风格很多公司采用了前后端分离模式后,后端仍然采用以往的传统风格,这是不合理的,风格的应该是前后端分离的最佳实践。 showImg(https://segmentfault.com/img/bVFC8f?w=690&h=360);早期的web开发是不分前端后端的。互联网进入Web2.0时...

    whlong 评论0 收藏0
  • 前后分离的总结

    摘要:如何去解决这些问题前后端分离大部分的互联网公司都分成了前端团队和后端团队。方案一采用架构业界很多公司会采用,单页应用的架构,这种架构是天然的前后端分离的。方案二淘宝的大前端方案中途岛上图是淘宝基于的前后端分离分层,以及的职责范围。 我们遇到了什么问题? 1.前端无法调试后端未完成的 API:如果后端同学还没有完成 API 开发,那么前端同学就不能对这个 API 进行开发。之前我们都是在...

    enrecul101 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<