开源项目提炼之法(上)

482 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

序言

今天我们要看的项目是 directus 中的一部分,其中关于存储的设计,非常巧妙,值得我们细细考量,学习和借鉴。今天我们从自己设计对比他人设计的角度出发,来看一看该开源项目中有哪些值得学习的地方。

我们要实现的什么

Web API SDK 用于向开发者提供快速的 Web API 访问能力,利用该 SDK 提供的 API,我们就可以轻松地实现对数据的操作。

实现功能需要考虑的问题

  1. 如何保证数据的安全性?即用户认证后才能访问 Restful API。
  2. 如何从服务器上获取数据?即我们需要集成 HTTP Client
  3. 如何对返回的数据进行存储?即我们可以对已返回的数据进行存储
  4. 如何保证本地持久化数据的安全性即持久化的数据,可以考虑进行加密处理,一般采用对称加密。
  5. 如何保证 Token 的安全性?即我们 Token 要提供过期时间,避免 Token 泄露导致数据异常
  6. 如何支持 Token 自动续期,以满足在安全性的前提下,保证用户的使用体验?
  7. 如何设计 SDK 对外提供的 API?可考虑按照功能点进行拆分,可拆成不同Service(服务)或Handler(处理器)
  8. 如何定义 SDK 返回的数据格式?即可以通过接口的形式,描述返回的数据格式。
  9. 如何允许保证 SDK 灵活可扩展?即可进行按照功能点进行模块化设计,面向接口进行编程。比如存储层,可先定义Storage 接口,然后再根据不同的存储方式,定义不同的实现类

image.png

我们由上图知道该功能一共分为6个主要模块,每个模块有多种不同的实现方式,或者是需要支持多种配置,所以每个功能都是一个独立的模块。我们可以采用分层架构的思想将其区分开来,分模块开发。

认证层

首先我们需要验证用户,为了支持多种验证方法,我们可以在这一层实现多种认证方式,具体采用哪一种又外部配置选择。

传输层

我们获取数据的方式多种多样,为了在不同的场景使用不同的请求方式,所以我们把这一层的实现叫做传输层。

存储层

获取完数据,需要对数据进行存储,你可以存在内存中,硬盘中,浏览器中等等,多种多样,为了支持适配,我们也要抽成一个独立的模块,叫做存储层。

服务层

我们还需要做很多细致的操作,例如Token的安全问题,以及一些公共方法的实现,我们需要在一个模块中进行统一管理和实现,方便其他模块的使用。

项目结构目录分析

分析完成以后,我们就按照分析的方向去源码中找到一一对应的地方,看作者是如何做这些架构和实现的。 这是我们主要研究的SDK文件目录,我们看到,作者把他分为3个部分:

image.png

image.png

image.png

  1. 最外层的auth,storage,transport,就是我们上面说的用户认证,数据存储,数据请求的接口定义,我们通过这些文件可以简单明了的知道这个SDK的主线程有哪些,分别包含什么方法和如何使用。
  2. base 文件夹里面是最外层定义的这些接口方法的实现,也就是具体功能对应 的实现,我们可以根据接口名找到对应的实现,清晰明了。
  3. handlers 文件夹内,就是该SDK需要用到的各种方法的,你想要的新增的任何方法都可以定义在里面做统一管理。

项目主线开始分析

我们先从项目主体 directus.ts 开始看,看下这个项目中都有些什么。

image.png

我们发现directus 插件的内容一览无余,这就是面向接口编程的好处,先定义好接口,想好思路,再进行开发,条例清晰。最上面三条是该插件的核心,认证层的用户认证,传输层的数据请求,存储层的 storage。下面是该组件扩展的一系列服务,接下来我们从核心出发,按流程去读。

Auth

我们在主目录看到auth的接口定义 我们看到 用户认证模块接受3个参数,有4个方法:

image.png

  1. 只读属性token 验证用户
  2. 只读属性password 验证密码
  3. 只读属性 expiring token是否自动延期
  4. 登陆方法 login
  5. 刷新方法 refresh
  6. 本地登陆 static
  7. 登出 logout

我们再去base 文件夹找到用户验证模块的具体实现

Storage

image.png

我们在主目录看到 storage 的接口定义 storage.ts 我们初步分析得知 其中包含三个参数,和三个方法。