Fork me on GitHub

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.


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.


the hexagonal architecture might relate with your goal. are you familiar with it?


Nope, that looks like a good thing to research, thanks!

🙌 3

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 is a good read!

👍 3

We have an api at work, where the transport is I don't particularly like, but provides a unified abstraction over websockets and long polling), and the api is defined as a graphql endpoint


Graphql is ok, and it gives you some bounds and lets you talk about synchronous request/response kind of messages and asynchronous subscription kinds of messages


The server side is using lacinia to process the graphql


An alternative would be to look at something like grpc's service (server?) language, which I guess is actually part of the protocol buffer language, buy let's you describe a service as a collection of kind of rpc calls with some asynchronous streaming stuff

hiredman01:12:45 is an idea I had but havent pursued too deeply, which describes a (stateful) api as a collection of specs for messages, and states where those messages are valid, inspired by ubf


I didn't know graphql had support for subscriptions. that's pretty cool. looking at the lacina docs for them now.


Will also look into grpc and that gist, thanks!

Ben Sless09:12:46

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?

Ben Sless15:12:17

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?)

Ben Sless17:12:43

Yes, or something to that effect

👍 3
Ben Sless12:01:01

@U064UGEUQ 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

Ben Sless20:01:51

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.