On 31 Jul 2013, at 09:58, Francis Fish <[email protected]> wrote:

> ... actually just have a service for uniqueness you pass a set to ... ?
> 
> Yeah, but why? I can't see what all this extra complexity gives you when the 
> mythical "next guy" (or gal) comes to pick up the code and work with it it 
> will just confuse them, it could be that the user example is too simple. You 
> can create a unique key on the database, in the old days we used to push most 
> of this stuff into the database because it was the single source of truth - 
> now there are services everywhere but I often wonder if the old strategy of a 
> well-designed DB with the constraints enabled (sigh) was easier.

Ah, the single source of truth in my system can't easily answer the question 
"Is attribute X unique across entities of type Y?". I'm using event sourcing 
(and CQRS), and this is a well-known problem, called "set based constraints". 
(It's asked repeatedly on event sourcing / CQRS forums). 

I have a complete record of every state change (event) of every entity in the 
system, which includes changes of usernames. What I need to do to answer this 
username availability question is generate from these events a list of 
usernames in use, then the implementation of the service method can be 
something along the lines of "SELECT count(username) > 0 FROM usernames WHERE 
username = 'foo';" Actually my current implementation is this: 

    class UserService
      # ...
      def username_available?(username)
        !@registered_users.record_for(username: username)
      end
      # ...
    end

While at first I was agreeing with you that this adds complexity, it then 
occurred to me that one of the HTTP resources I want – 
"/api/usernames/<candidate_username>" (for the live ajax username check on the 
signup form) – also needs to make this query. So this removes duplication, and 
as it works without constructing a whole User object, has less accidental 
complexity than I'd have if I'd made individual users able to determine if 
their username was available.

While this is a bit of a pain, using event sourcing makes it relatively easy to 
answer questions like "Was this username available last thursday?" or "Which 
usernames have been used more than once by different people?", both of which 
would be impossible to answer if all the system had was a relational snapshot 
of the current state, unless these questions had been thought of in advance. Of 
course, username re-use is probably about the lowest value question you could 
ask most systems, it just happens to be the area I'm working on now.

> As a community we have a problem, where the default Rails app first iteration 
> gives you what is effectively an API on top of a (possibly so-so design) 
> database.

Yes, this is the problem I've encountered myself and which I'm testing 
solutions to.

> So now we're trying to come up with ways that guarantee the flex we need for 
> the second to N iterations, which is a really good thing. But this feels too 
> heavy for the majority of trivial things we do all day.

The purpose of this project is to teach myself event sourcing (and also CQRS, 
and a variety of other domain-driven design techniques that go well with it). 
The game I'm building is simple enough I could feasibly have built it in 
Sinatra in a weekend, but that's not the point. I want to evaluate the 
technique of event sourcing so I have a better idea which problem contexts it 
will help with.

I'm not trying to find a better way of doing trivial things, I'm trying to find 
a better way of doing important things, things people will pay a lot of money 
to have solved, but which can't easily be solved with Rails.

Eric Evans said about DDD that you should only do it for your core business, 
the thing that differentiates you from competitors. This isn't a commercial 
project, it's a research project.

> Having played with Erlang and Chicago Boss I think in fact what you're 
> describing is really easy to implement with them and already part of the 
> abstraction layer, and in fact that's what I'd do - just go functional and 
> persistent and the hell with it. There's that new Ruby-like language that 
> talks Erlang? Elixir?

I took a look at Chicago Boss and it appears to operate on something quite 
Active-Record-like (as in the pattern, not the library). It doesn't appear to 
be solving the same problem (domain model - database coupling), but I didn't 
dig too far.

Cheers
Ash

-- 
http://www.patchspace.co.uk/
http://www.linkedin.com/in/ashmoran

-- 
You received this message because you are subscribed to the Google Groups 
"NWRUG" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/nwrug-members.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to