小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
序言
今天我们要看的项目是 directus 中的一部分,其中关于存储的设计,非常巧妙,值得我们细细考量,学习和借鉴。今天我们从自己设计对比他人设计的角度出发,来看一看该开源项目中有哪些值得学习的地方。
我们要实现的什么
Web API SDK 用于向开发者提供快速的 Web API 访问能力,利用该 SDK 提供的 API,我们就可以轻松地实现对数据的操作。
实现功能需要考虑的问题
- 如何保证数据的安全性?即用户认证后才能访问 Restful API。
- 如何从服务器上获取数据?即我们需要集成 HTTP Client
- 如何对返回的数据进行存储?即我们可以对已返回的数据进行存储
- 如何保证本地持久化数据的安全性即持久化的数据,可以考虑进行加密处理,一般采用对称加密。
- 如何保证 Token 的安全性?即我们 Token 要提供过期时间,避免 Token 泄露导致数据异常
- 如何支持 Token 自动续期,以满足在安全性的前提下,保证用户的使用体验?
- 如何设计 SDK 对外提供的 API?可考虑按照功能点进行拆分,可拆成不同Service(服务)或Handler(处理器)
- 如何定义 SDK 返回的数据格式?即可以通过接口的形式,描述返回的数据格式。
- 如何允许保证 SDK 灵活可扩展?即可进行按照功能点进行模块化设计,面向接口进行编程。比如存储层,可先定义Storage 接口,然后再根据不同的存储方式,定义不同的实现类
我们由上图知道该功能一共分为6个主要模块,每个模块有多种不同的实现方式,或者是需要支持多种配置,所以每个功能都是一个独立的模块。我们可以采用分层架构的思想将其区分开来,分模块开发。
认证层
首先我们需要验证用户,为了支持多种验证方法,我们可以在这一层实现多种认证方式,具体采用哪一种又外部配置选择。
传输层
我们获取数据的方式多种多样,为了在不同的场景使用不同的请求方式,所以我们把这一层的实现叫做传输层。
存储层
获取完数据,需要对数据进行存储,你可以存在内存中,硬盘中,浏览器中等等,多种多样,为了支持适配,我们也要抽成一个独立的模块,叫做存储层。
服务层
我们还需要做很多细致的操作,例如Token的安全问题,以及一些公共方法的实现,我们需要在一个模块中进行统一管理和实现,方便其他模块的使用。
项目结构目录分析
分析完成以后,我们就按照分析的方向去源码中找到一一对应的地方,看作者是如何做这些架构和实现的。 这是我们主要研究的SDK文件目录,我们看到,作者把他分为3个部分:
- 最外层的auth,storage,transport,就是我们上面说的用户认证,数据存储,数据请求的接口定义,我们通过这些文件可以简单明了的知道这个SDK的主线程有哪些,分别包含什么方法和如何使用。
- base 文件夹里面是最外层定义的这些接口方法的实现,也就是具体功能对应 的实现,我们可以根据接口名找到对应的实现,清晰明了。
- handlers 文件夹内,就是该SDK需要用到的各种方法的,你想要的新增的任何方法都可以定义在里面做统一管理。
项目主线开始分析
我们先从项目主体 directus.ts 开始看,看下这个项目中都有些什么。
我们发现directus 插件的内容一览无余,这就是面向接口编程的好处,先定义好接口,想好思路,再进行开发,条例清晰。最上面三条是该插件的核心,认证层的用户认证,传输层的数据请求,存储层的 storage。下面是该组件扩展的一系列服务,接下来我们从核心出发,按流程去读。
Auth
我们在主目录看到auth的接口定义 我们看到 用户认证模块接受3个参数,有4个方法:
- 只读属性token 验证用户
- 只读属性password 验证密码
- 只读属性 expiring token是否自动延期
- 登陆方法 login
- 刷新方法 refresh
- 本地登陆 static
- 登出 logout