Skip to content

[Proposal/RFC] Split Parse Server Extensions from Core Repo #761

Closed
@asciimike

Description

@asciimike

Recently there's been a lot of activity in creating extensions to Parse Server's capabilities in the form of third party connectors to different services: Files (#545, #708, #716), Push (#711), Analytics (#719), and Mail (#627), and the Database (starting with #698) have all seen contributions to add new services or interest in modular components. This is awesome, as it shows some serious flexibility as well as community commitment--keep it up!

That said, as we start adding more and more extensions to the core feature, we're starting to encounter a few problems:

  1. Testability and key management: Thanks to @flovilmart, a simple framework for testing multiple adapters exists (9287afc)! Unfortunately, testing third party services on the shared Parse infrastructure is increasingly difficult due to key management--unless the Parse Server Travis server maintains keys for all the services (which is untenable), CI tests on third party modules can't easily exist. Heavy mocking of each service could also solve this problem, though this is a challenge and a barrier to entry.
  2. Imports: As an example, we'll soon be importing AWS, Azure, and GCP node modules to allow for cloud hosted file storage--which seems like a bit of overkill as it's unlikely that a developer will want to use all three (let alone any one of the three). If every feature (push, analytics, mail, etc.) has the top three modules involved, we'll soon be having quite the party downloading half of NPM every time we want to update our server ;)
  3. Onboarding/ease of creation: As more and more extensions get added to the core codebase, we risk making it harder to maintain the existing code, as well as make it harder to add extensions, since the knowledge required to work in the codebase becomes higher. Modularizing code by creating similar, standalone chunks means developers interested in contributing to an area can more quickly and easily dive in to help.

With those problems in mind, I have seen/heard of (at least) three ways of approaching them:

  1. Split functionality up into use-case specific extensions: for instance, parse-server-extensions-files, parse-server-extensions-push, parse-server-extensions-mail, etc.
  2. Split functionality up into provider specific extensions: for instance, parse-server-provider-aws, parse-server-provider-azure, parse-server-provider-gcs, etc.
  3. Make everything independent: parse-server-extension-gcsadapter, parse-server-extension-sns, and parse-server-extension-foo all live independently. We could provide a set of base templates to help get started which feature basic jasmine tests and a parse-server testing rig (say a parse-server-extension-template repo.

1 has the advantage of providing a logical grouping of services which promotes testability and makes it logically easier for the related code to stay in lock step. It also lowers the barrier to entry for developers looking to add new features, since there are a number of well tested examples that can be easily added upon at once, and there's no need to seek approval from a whole number of different people in order to add a cross provider feature (say like what happened with createBucket() in FilesAdapter).

In this model, code could be imported to parse-server like so:

var S3Adapter = require('parse-server-extensions-files').S3Adapter(...);
var AzureBlobAdapter = require('parse-server-extensions-files').AzureBlobAdapter(...);
var GCSAdapter = require('parse-server-extensions-files').GCSAdapter(...);

2 has the advantage of solving key management and imports far better, since it is ideally a single set of keys per provider, but I think it makes it harder for individual devs to contribute to a new extension (or a major feature on an existing extension) given that one would potentially have to talk to many more people and consensus gathering would be harder.

In this model, code could be imported to parse-server like so:

var S3Adapter = require('parse-server-provider-aws').S3Adapter(...);
var AzureBlobAdapter = require('parse-server-provider-azure').AzureBlobAdapter(...);
var GCSAdapter = require('parse-server-provider-gcp').GCSAdapter(...);

3 is the wild west approach, and allows the ultimate flexibility with the ultimate potential for confusion and lack of discoverability. Obviously anyone can already do this, but the barrier to entry is much higher. A template repo would help significantly, but might still result in similar feature sets or providers behaving differently from feature to feature.

In this model, code could be imported to parse-server pretty much however...

var S3Adapter = require('sams-s3-adapter').S3Adapter(...);
var AzureBlobAdapter = require('alexas-azure-blob-adapter').AzureBlobAdapter(...);
var GCSAdapter = require('garys-gcs-adapter').GCSAdapter(...);

What are the other options I'm missing that are worth discussing?

Orthogonal to this discussion would be (aka, doesn't have to be discussed now), once things are pulled out, would there be a standard set of services packaged with parse-server core: say Mongo, S3, GCM, etc. (original services)?

I know the core maintainers have been discussing this in a number of PRs and issues, so I figured it might be good to consolidate some of the thoughts. I'd also appreciate feedback from the community on which approach they like most and why they like it (which features are they anticipating using/already use), and what concerns they with this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions