loopback-component-storage源码分析及自定义实现--添加阿里云OSS支持

原文地址:https://www.jianshu.com/p/9b05e14ebc67

1. 介绍

使用LoopBack在进行项目开发时,如果有文件的上传下载功能需求,可以使用LoopBack提供的模块: loopback-component-storage。该模块不仅支持本地文件存储,还可以对接远程远程文件提供商如Amazon,Rackspace等,通过该模块你只需要填写几行简单的配置信息即可实现文件上传下载功能,可谓十分的便利。但是该模块不支持阿里云OSS,只能自己实现,已实现的版本地址为: loopback-component-storage。

注:本次分析源码版本为e76d571a8c90cc4a1c50f2bf3966edaaf79eec40这个commit

2. 官方示例演示

运行官方example,跑起来会默认生成以下接口:

loopback-component-storage源码分析及自定义实现--添加阿里云OSS支持_第1张图片
image.png

而这些接口对应的Model方法为:


loopback-component-storage源码分析及自定义实现--添加阿里云OSS支持_第2张图片
image.png

API

datasource.json的配置如下:

{
  "db": {
    "name": "db",
    "connector": "memory"
  },
  "storage": {
    "name": "storage",
    "connector": "loopback-component-storage",
    "provider": "filesystem",
    "root": "./server/storage"
  }
}

3. 源码分析

ok,现在开始查看loopback-component-storage源码。

打开package.json,发现"main": "index.js",
查看index.js发现了storage-connector接着发现了storage-service,在storage-service看到(第68行):

StorageService.prototype.getContainers = function(cb) {
  this.client.getContainers(function(err, containers) {
    if (err) {
      cb(err, containers);
    } else {
      cb(err, containers.map(function(c) {
        return map(c);
      }));
    }
  });
};

发现模型的方法如getContainers等都是通过this.client这个对象来执行,而这个对象是在通过factory.createClient(options)创建的(第36行):

this.client = factory.createClient(options);

这个options就是在example项目定义的datasource.jsonconnectorloopback-component-storage的对象,即示例演示中的storage对象。

接着打开factorycreateClient:

/**
 * Create a client instance based on the options
 * @param options
 * @returns {*}
 */
function createClient(options) {
  options = options || {};
  # 1. 提取provider,如果不存在则默认为filesystem
  var provider = options.provider || 'filesystem';
  var handler;

  try {
    // 2. 先试着在本地providers下加载
    handler = require('./providers/' + provider);
  } catch (err) {
    try {
      // 3. 如果失败则加载外部模块
      handler = require(provider);
      if (!handler || !handler.createClient) {
        // 4. handler不存在或不合法就直接使用pkcloud的storage
        handler = require('pkgcloud').storage;
      }
    } catch (err) {
      // 5. 再失败就直接使用pkcloud的storage
      handler = require('pkgcloud').storage;
    }
  }
  patchContainerAndFileClass(provider);
  return handler.createClient(options);
}

重点关注第二步,先看下providers目录,发现只有一个filesystem文件夹,说明本地只支持providerfilesystem的配置,其他的均会抛出异常。现在看下filesystem目录下的index.js文件(第26行):

module.exports.createClient = function(options) {
  return new FileSystemProvider(options);
};

找到filesystem类型的createClient方法,创建的是一个FileSystemProvider对象,在往下看(第97行):

FileSystemProvider.prototype.getContainers = function(cb) {
  var self = this;
  ....
};

发现接口对应方法,也就是在这里定义的。

结论

到这里就可以知道如何自定义provider了:

  1. 在providers目录下创建自定义provider目录(如:aliyun)
  2. 在目录下exports出来的对象中实现createClient(options)方法
  3. createClient(options)返回的对象中实现接口对应方法,如getContainers等。

当然也可以直接全部写在一个文件里面,这里定义等步骤只是为了与已存在等模块风格一致。

4. 自定义

完整示例请参考:loopback-component-storage

5. Reference

  1. Storage component
  2. loopback-component-storage

你可能感兴趣的:(loopback-component-storage源码分析及自定义实现--添加阿里云OSS支持)