Hi, I am developing an app using react-native/expo (not settled yet), this app is a mobile first app. It is a re-frame app. The data needs to be stored locally first and data will also be loaded from local db. Data will be synced to server after the fact. I am exploring options for storing data locally, sql server seems to be one of the choices. Is there any other mature choice ? I would have preferred a persistent datalog compliant db for native development, are there any options in this regard ?
on the server my db of choice is crux
only if I can find an equivalent db for the client side, otherwise will go for sql on both ends.
Breaking my holiday break to say that this interests me too. Happy to compare notes after the holiday week. We’re currently doing this by adding dozens of callback URIs...
crux with xodus or lmdb backend?
There are a lot of services that offer rest+websocket apis but I find I usually want to work at a higher level then this. In my app I just want to be able to request or initiate streams of parsed, domain spec’d data, separately from the management of websocket/http connections. I suppose the protocols would look something like this:
(defprotocol X
(request! [this msg ch] "request that receives exactly one response (on ch)"))
(defprotocol Y
(send! [this msg] "(asynchronous?) send a message which may trigger response messages.")
(recv-ch [this msg ch] "return a channel of all response messages"))
That is, I want to work with data-request->data response but use MY definitions of data instead of the websocket/http data. So this layer would exist between the websocket/rest apis and the high level clojure functions like (get-my-thing …)
My question is, are there any examples of this, or terminology for describing this “layer”? It seems like almost every app using rest/websocket should want something like this, at least if there’s more than ~10 endpoints? But the lack of examples makes me wonder if I’m wrong about that or missing something?
Maybe this relates to CQRS/event sourcing? But from what I know of that it doesn’t feel 100% like what I’m after either.Sometimes I think about generalizing the two interesting APIs of client/server and producer/consumer to protocols. I don't really care about the implementation, but about the language of the system (see what I did there?). I want to program to the system abstraction, not the implementation
What do you mean by generalizing the two apis? Do you mean just have a layer over them both, with protocols specifying the actual stuff you do?
No, I mean generalizing each one of them on its own, i.e. have protocols for Consumer/Producer and Client/Request/Server
Gotcha, would they be along the lines of the ones I posted:
(defprotocol X
(request! [this msg ch] "request that receives exactly one response (on ch)"))
(defprotocol Y
(send! [this msg] "(asynchronous?) send a message which may trigger response messages.")
(recv-ch [this msg ch] "return a channel of all response messages"))
or something different? (these would be the client/request/server and I guess a producer?)Yes, or something to that effect
@jjttjj a big question for me is whether these are separate interfaces or one, for example Producer and Client both send!
, but the main differences are:
• for a producer send!
returns an indication send succeeded, while for a client it returns a response
• Producers can also reflect backpressure, while for clients it makes less sense (does it?)
Yeah I've wondered this type of thing too, and I'm not quite sure either, your bullet points sum it up pretty good
It's made even more complicated by the fact you could implement either one using the other. I think the biggest difference relates to the return value's type. A non transactional producer only needs a boolean response, while a client needs more data.
the hexagonal architecture might relate with your goal. are you familiar with it?
Nope, that looks like a good thing to research, thanks!
as an additional pointer, your core API might be better descirbed as pure inputs/outputs (data/data) instead of channels, streams etc channels and such are essentially FP-impure and preclude some techniques, especially related to unit-testing https://blog.ploeh.dk/2016/03/18/functional-architecture-is-ports-and-adapters/ is a good read!