off-topic

https://github.com/clojurians/community-development/blob/master/Code-of-Conduct.md Clojurians Slack Community Code of Conduct. Searchable message archives are at https://clojurians-log.clojureverse.org/
murtaza52 2020-12-30T07:09:35.308200Z

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 ?

murtaza52 2020-12-30T07:11:45.309900Z

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.

orestis 2020-12-30T07:12:00.310400Z

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...

euccastro 2020-12-30T07:25:01.310900Z

crux with xodus or lmdb backend?

dominicm 2020-12-30T08:42:53.314100Z

You'll need a redirector.

dominicm 2020-12-30T08:43:10.314300Z

One central place that just forwards to where it's supposed to be.

rutledgepaulv 2020-12-30T14:12:09.315600Z

I built a product that was multi tenant a few years back and we registered separate oauth credentials with our identity provider for each tenant domain. I realize that's more work but the isolation we ended up with was nice. We then automated all aspects of tenant provisioning so adding a tenant was still as simple as entering a name and clicking a button

rutledgepaulv 2020-12-30T14:16:14.315800Z

I should add: our apps fetched their config for a tenant (like the oauth credentials) from another service at runtime so there wasn't any need to update settings / secret files with new credentials for each tenant.

rutledgepaulv 2020-12-30T14:24:09.316Z

But as dominicm said, if you want just one then you'll need a redirect that inspects some aspect of the state query param to determine the original tenant I think

2020-12-30T14:40:51.316400Z

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.

Ben Sless 2020-12-31T09:43:46.322Z

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

2020-12-31T15:12:09.326600Z

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 Sless 2020-12-31T15:15:17.326800Z

No, I mean generalizing each one of them on its own, i.e. have protocols for Consumer/Producer and Client/Request/Server

2020-12-31T15:18:33.327Z

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 Sless 2020-12-31T17:37:43.327500Z

Yes, or something to that effect

1👍
Ben Sless 2021-01-01T12:00:01.349Z

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

2021-01-01T20:24:19.425400Z

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 Sless 2021-01-01T20:29:51.426900Z

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.

dominicm 2020-12-30T15:56:00.316500Z

There's plenty of services that don't allow that kind of dynamic registration. Although it maybe depends on how you're isolating tenants too

vemv 2020-12-30T16:08:37.316700Z

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

2020-12-30T16:20:37.316900Z

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

1🙌
vemv 2020-12-30T16:23:29.317200Z

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!

1👍
kenj 2020-12-30T18:49:11.317700Z

So after thinking on it all day yesterday, I’m going down the route described above, namely encoding the origin domain into the state field sent to the auth server, and then writing an intermediate callback that will do nothing but decode the state, pull out the encoded origin domain, and redirect to the final callback at the correct domain.