meeshkan / unmock-js

Fuzz test your REST API calls
https://unmock.io
93 stars 8 forks source link

WIP RFC: Simplify architecture #372

Closed ksaaskil closed 4 years ago

ksaaskil commented 4 years ago

Motivation

Current Unmock architecture feels a bit difficult to understand and hard to extend. Modifying Unmock requires, I think, rather intricate knowledge of the internals.

I think it should be possible to simplify the architecture to allow more easily extending it to different environments and to make it easier for new developers to understand.

Overview of current core components

Service

Describes an API service such as “GitHub”. A service essentially corresponds to a single OpenAPI specification. Exposes properties such as state, spy, and reset().

Delegates a lot of logic to ServiceCore. Strongly coupled to OpenAPI.

ServiceStore

Container for all services defined by the user or loaded from file system. Provides access to services via services property. Services can only be accessed by their "name", which is not always intuitively clear.

Faker

Matches serialized request to a corresponding service and generates response. Throws an error if no matching operation is found. Most of the mock generation logic is in generator.ts.

IInterceptor

Abstraction for intercepting (HTTP) requests and serving back mock data. Interceptor is responsible for serializing the request to ISerializedRequest object, passing it to Faker to generate ISerializedResponse and delivering a response. For an example, see NodeInterceptor and FetchInterceptor.

Backend

“Manager”-kind of class wrapping generic environment-unspecific behaviour.

UnmockPackage

Class implemented by unmock object exported by default from unmock-node and unmock-browser. Exposes options such as unmock.randomize.on(), services via unmock.services.githubv3, unmock.nock API for adding services programmatically, unmock.on() for switching on interceptor and loading services, etc.

ServiceDefLoader

Services are loaded when Backend is initialized. Currently this is a no-op in environments other than Node.js, where services are loaded from filesystem's __unmock__ folder.

Architecture diagram

Essentially looks like this.

Screenshot 2020-01-08 at 15 25 43

Requirements

WIP

Suggestions for improvement

WIP

Provide access to services not by name but by their URL

Interceptor should accept a Faker or CreateResponse

More plugin-like architecture?

Get rid of Backend

Create an abstraction for services that could also work with GraphQL

Get rid of nock API

It feels very out-of-place, for example, in browser and React Native environments.