Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggested Patterns for Middlewares #500

Open
graphographer opened this issue Feb 24, 2023 · 6 comments
Open

Suggested Patterns for Middlewares #500

graphographer opened this issue Feb 24, 2023 · 6 comments
Labels
❔ question General question

Comments

@graphographer
Copy link

graphographer commented Feb 24, 2023

I've been refactoring a rather large part of our codebase to use Mobx Keystone, and (hopefully) some modified form of Domain Driven Design on the client side and server. Although the Client/Server example given in the documentation is very helpful, I'm having difficulty understanding exactly how it might be applied to some of our use-cases, or whether it was never intended to be used in these particular ways.

Specifically, I want to use our websocket connection to both provide hydrated models to the client side, while possibly formalizing that initial fetch in terms of Mobx Keystone models. The documentation makes it clear that the intended use of onActionMiddleware is mainly to replicate actions remotely: that is, to create/modify models elsewhere and then subsequently synchronize those changes locally.

Is there a possible or recommended pattern for using any of the middleware functions (like actionTrackingMIddleware) to essentially call back-end services in order to return model data to the client? Models wouldn't be created or modified on the server, but rather, the server would simply return model snapshots to the client.

So, for example, instead of doing something like myNetworkTransportInterface.fetch('myModels') it's more like 'myDomainModel.fetchAction('myModels')` and that's intercepted by an action middleware at the application layer which passes it to the server via a websocket or http request. The serialized form of that action is then run on a Mobx Keystone model on the server which is designed really only to return data (like a controller for a GET request).

Sorry if this is unclear, I may really be asking for a new feature or design paradigm that Mobx Keystone doesn't provide.

@xaviergonz
Copy link
Owner

xaviergonz commented Feb 26, 2023

Basically you'd want to do something like this (assuming you want a "pessimistic" model, this is, whenever you do an action you cancel it locally and only replicate it whenever it is sent by the server):

    1. the client opens a WebSocket to the server
    1. the server sends the "initial" snapshot
    1. the client uses fromSnapshot to instantiate a model
    1. the client uses onActionMiddleware, when the action is a local one it is cancelled and the patch is sent to the server (which is then applied to the server snapshot and replicated to all the other clients)

Id you want an "optimistic" model, where you apply local actions directly, without cancelling them, and then possible conflicts are auto-fixed then probably you might have more luck with a Conflict-Free Replicated Data Type (CRDT), such as https://github.com/yjs/yjs or https://automerge.org/

@graphographer
Copy link
Author

Thank you for your response. I understand that what you are suggesting is essentially what is given in the "Client/Server" example on the documentation website.

However, my question is whether action middlewares can be used to describe step ii of your points above. That is, I want to avoid having many individual websocket messages for fetching specific data if the Mobx Keystone model actions themselves can do that.

@xaviergonz
Copy link
Owner

there's no Middleware for it, but you can just use getSnapshot and fromSnapshot

@graphographer
Copy link
Author

Now that I've been working for a few weeks with remotely replicating action calls, I have a bit of a better conceptual grasp of how Keystone works more generally.

So my new question is this: Is there a straightforward way to "extract" the return value of a serialized action call result? That is, can I have a client send a sort of serialized standalone action to the server and parse the serialized response action (that is, as an alternative to getSnapshot for example)?

I do sense that I'm simply asking for non-existent features, so do not worry about disappointing me :) Thank you so much for all the great work you have put into Keystone.

@xaviergonz
Copy link
Owner

applyAction should return any value that might be returned from the action call being called

@xaviergonz
Copy link
Owner

or returnValue inside the object returned by applySerializedActionAndTrackNewModelIds / applySerializedActionAndSyncNewModelIds

@xaviergonz xaviergonz added the ❔ question General question label Mar 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
❔ question General question
Projects
None yet
Development

No branches or pull requests

2 participants