/phenyl

JavaScript Server/Client framework to SSoE (State Synchronization over Environments)

Primary LanguageTypeScriptApache License 2.0Apache-2.0

Phenyl - State Synchronization over Environments CircleCI

WORK IN PROGRESS

Phenyl is a series of JavaScript libraries for both client-side and server-side, which focuses on State Synchronization over Environments(SSoE).

ServerSide Phenyl provides an API server like MBaaS(Mobile Backend as a server). ClientSide Phenyl provides Redux module system. Within these two environments, States are Synchronized in various ways.

State Synchronization over Environments (SSoE)

State Synchronization over Environments is the main concept of modern applications.

For example, if you use RESTful API, you can synchronize server and client state through following HTTP methods:

  • Acquire server state of user by GET /user and provide user profile view by acquired user entity.
  • User updates user name at profile view, app update user entity in the client side and app POST or PATCH /user.
  • User delete account, app clear the client state and app execute DELETE /user

It's popular method of SSoE. So, many people create RDB, write API server to transform Data to Entity and communicate with client, write fetch code in client, client transform Entity to data for view, client update entity and notify to server, server save updated entity to DB and so on. Additionally error handlings are neccessary in practice.

Phenyl provides simpler solution to handle SSoE based on the following 4 concepts:

  • State as one big JSON
  • OAD: Operations as Data
  • MongoDB-like operations
  • Git-like synchronization

State as one big JSON

JSON is very useful format for JavaScript. It has some basic types like string or boolean and it's easy to serialize and deserialize. We represent the entire app state as one big JSON.

OAD: Operations As Data

Phenyl handles all CRUD operations on data, such as creating an entity, reading the data in an entity, updating a property in an entity, and deleting an entity as data. The history of all operations is also saved as in the state. This concept allows us to easily reproduce and debug any situations we want.

MongoDB-like operations

Phenyl provides MongoDB-like operations.

In a mongoDB shell, CRUD operations are performed as following:

> db.testUser.insertOne({_id: "test1", name: "Test1"})
{ "acknowledged" : true, "insertedId" : "test1" }

> db.testUser.findOne({_id: "test1"})
{ "_id" : "test1", "name" : "Test1" }

> db.testUser.updateOne({name: "Test1"}, {$set: {favoriteFood: "banana"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

> db.testUser.findOne({_id: "test1"})
{ "_id" : "test1", "name" : "Test1" , "favoriteFood": "banana" }

> db.testUser.deleteOne({"_id": "test1"})
{ "acknowledged" : true, "deletedCount" : 1 }

> db.testUser.findOne({_id: "test1"})
null

In Phenyl client, the operations are performed as following. (This code is simplified.)

// omission prepare httpClient and preSession
const inserted = await phenylClient.insertAndGet(
    {
        entityName: "testUser",
        value: {
            id: "test1",
            name: "Test1",
        }
    },
    preSession.id
);

console.log(inserted.entity)
// -> { id: "test1", name: "Test1" }

const updated = await phenylClient.updateAndGet(
    {
        entityName: "testUser",
        id: "test1",
        operation: {
            $set: { favoriteFood: "banana" }
        }
    },
    preSession.id
);

console.log(updated.entity)
// -> { id: "test1", name: "Test1" , faboriteFood: "banana" }

await phenylClient.delete({ entityName: "testUser", id: "test1" })

If you have used mongodb, you will soon get to be friendly with the API of Phenyl😎.

Git-like synchronization

Phenyl synchronizes between server and client by using git-like command. You can acquire server side entity by pull and update by push. This allows us to handle offline oepration easily.

Phenyl Family

ServerSide Libraries

ClientSide Libraries

Common Libraries

sp2

Phenyl is powered by sp2, a set of JavaScript modules used for state operations.

Usage

Phenyl needs you to implement 2 features, one is GeneralTypeMap and the other is functionalGroup. GeneralTypeMap is type definition that describes shape of request and response of each entity and auth information. functionalGroup is implementation to notify Phenyl about the domain that we want to use. If you want to know more details, see example.

License

Apache License 2.0