So in my mind, the usual users table that we are used to having, is going to split in two:

  • whatever data is within the Identity Provider
  • the domain specific data (user.facialHairStyle) is going to still stay in the user table. One difference is that it will be missing the regular properties covered by the Identity Provider: name, sex, mail...

Gotta be honest. I far from like this. First dumb example that comes to mind: User registers, the app handles that by creating a user entry with domain-specific data with id of the identity pool entry. What if the user entry creation fails? Do I need to invent rollback procedures? Do I unregister the user?

  • Why might the user entry creation fail?... Seems to me like you need to treat AWS Cognito as a discrete service. It doesn't have anything to do with your domain proper... not really. The only reason you're calling it is to get an authentication. – Robert Harvey Oct 25 '17 at 18:58
  • @RobertHarvey The other equally big reason is storing big chunk of the user data. Problem is, that it's not big enough, or flexible enough so that I could ditch the user table all together. – Birowsky Oct 25 '17 at 19:10
  • 1
    Nor would I expect it to be. The purpose of Cognito is authentication and authorization, not comprehensive business domain data and logic capture. I fully expect you to still need a User table. – Robert Harvey Oct 25 '17 at 19:23
  • @RobertHarvey you sir, don't seem worried at all having User table that augments Identity entries. Your reputation says I shouldn't be either. – Birowsky Oct 25 '17 at 19:32
  • For the same reasons that I distinguish between my house and its deed. Or me and my driver's license. – Robert Harvey Oct 25 '17 at 19:34

I’ve done this before, where data in a third party service needs to be in sync with data stored in my in-house SQL database.

The best way that I could come up with was to start a local database transaction, provisionally insert the local data, reach out to the third-party service and do my data creation / insert there, verify the third-party service call completed successfully and obtain any third-party ID as necessary, then within the same local database transaction update the requisite data, then and only then commit the database transaction.

If the third party service fails, you can rollback the transaction and you have no dangling local data. If the commit fails, you can rollback the third-party service creation manually.

The only downside is that if the third-party service is slow, you have the potential for long-running transactions which can be problematic and lead to deadlocks in specific cases.

But on the whole this works well enough when I’ve done it.

  • If you need greater scalability and want to avoid the locks that come with a transaction, you can have a status flag in your local database and use asynchronous message queues to make the data between the third party service and your own data eventually consistent. – RibaldEddie Oct 25 '17 at 21:52

Since you need two operations to succeed of fail together, you should use a transaction around them. Transactions are not committed to the table until marked complete. If one part fails, none of the changes will be written to the table. https://en.wikipedia.org/wiki/Database_transaction

If your data store does not support that, then do not begin the second transaction until after the identity creation succeeds.

  • @Tony, identity creation succeeds, then, we create user entry. Second operation can still fail. And I'd be left with blind identity. While solving this is possible, let's figure out how to NOT need to solve it at all. Why focusing on creating the user entity that pairs the Identity Provider? Ideally we would be able to save all domain-specific user data to the Identity entity. But it's far from flexible. No lists, no maps. We could serialize the shit out of them, but does everything need to have a drawback?! – Birowsky Oct 25 '17 at 19:07
  • It does appear that you could store field data plainly, but would have to serialize any lists or maps. Could you store the majority of name/value pair data in the UserPool and only store the lists and maps separately? If you put all of the required data in the UserPool then the biggest issue would be solved. I think you're right that the main options are serialization or manual rollback. – Tony Bishop Oct 25 '17 at 19:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.