Hi everyone,
I am new to event sourcing, although I have been a professional developer for about 6 years, mainly Xamarin mobile apps for Droid and iOS. I am familiar with hooking into APIs which drive the apps I work on, but have limited back end experience.
I am working on a project which I think can really benefit from using event sourcing and it is going well so far. I have been reading a lot and watching tonnes of presentations by Greg and others and I have (I think) a decent grasp of what I want to achieve and how I am going to do it for the most part.
I think occasionally connected mobile clients are particularly complex domain to apply this in for my first go at ES or CQRS, so I am finding it challenging, but it is too good an opportunity to pass up and also it is a dry run for later client facing work.
I would like some advice on one element in particular, if possible. I will try to explain without going into too much detail. Sorry if it is a bit long winded.
Background
-
-
A group of people will be invited to a project by a project admin.
-
-
-
They will be given geographically-based tasks (Go to these places, do these things).
-
-
-
Whilst in the field, they will need to work offline, collecting positional data and augmenting it with their observations.
-
-
-
When they come back online they need to be able to sync their data back to the server for the project admin to analyse.
-
I have taken my lead from Greg’s talk here:
https://skillsmatter.com/skillscasts/1980-cqrs-not-just-for-server-systems
I currently have ES up and running locally and I am pushing / pulling to it directly over http from the app for the time being.
The idea is that ultimately I will
-
-
Pull all unseen events from the server to the client on login / launch (Using EventStore as the master book of record)
-
-
-
Keep a copy of the domain logic in the client so that I can execute commands offline
-
-
-
Keep these commands and the pending events they generate in separate buckets to the pulled server events (using NEventStore w/ SQLite in the apps)
-
-
-
When pushing pending events to the server, if optimistic concurrency check fails, raise 'need to pull first'.
-
-
-
A pull in this case will:
-
-
Clear local events for that stream
-
Pull new events / rebuild domain models
-
Re-execute commands and resolve any conflicts
-
-
If push succeeds, clear local commands. Next pull will replace local events with server events.
-
Question
Ok, so the thing I am a bit stuck on is the group auth. Obviously eventually I don’t want to be pulling all events down to the mobile client, only those from streams which the user is authenticated to access.
The authentication will be group – based and controlled by the project admin. I am using Azure ADB2C via App Center as my directory service (client facing Active Directory essentially).
I am sketchy on the details of how I will deal with the server until I get there as it is the bit I have little experience with. I know I will need to have a VM which has a client facing API that acts as a proxy for ES which runs behind it on localhost. Access to the API will be secured with the Active Directory. When a user is authenticated I call ES with the ES-TrustedAuth header which contains the users ID and groups.
Beyond that it is a bit blurry.
Should the streams should have a GroupId in their meta data, then I can run a projection to partition them by that ID? That would get me to a point where I had all the events for one group in a single stream.
I’m still not sure how I then secure that projection’s endpoint at group level, unless I can somehow dynamically create an ACL group for it using the group’s ID, and then add users to that ACL group.
If I were to update a stream’s metadata to have an ACL with a $someGroupGuidId entry, then include an ES-TrustedAuth header in my request of “myUserId; someGroupGuidId” would that ‘just work’?
Perhaps I am missing something or looking at this from totally the wrong angle. I expect I am, given my lack of server-side experience. Just a pointer on which direction to go and some things to read or anything would be awesome J
Cheers! Ryan