1

I want to build an app that will have have several monoliths. My question (similar to this one) is, how do I centralize User model between these apps, i.e. how to deal with user management/authorization/authentication without duplicating code. For some context, I'm using code driven development with Django.

This is what I came up with:

===========       =======================       ===============
== App 1 == <---> = Shared API with DRF = <---> ==== App 2 ====
===========       =======================       ===============
= barcode =       = * Users             =       = web app for =
= scanner =       = * Roles             =       = shopping    =
= android =       = * Privilages        =       ===============
===========       = * User data         =
                  =======================
                             ^
===============              |
==== App 3 ==== <-------------
===============
= web app for =
= retailers   =
= to upload   =
= goods       =
===============

Is this good architecture when several applications need to share same users? Is there an alternative? For example, how would one extend this model to accept users that login, for example, using oAuth with Google account or similar? Is it possible to do this without using microservice architecture? Also, is it better to use GraphQL (to share User data as an Object) or REST for the API?

3
  • The key here is to not share data. That is, push it all the way to the top. Authentication/authorization are specific to the "view" of an application. Utilizing an API for authentication and storing data in a session is a good approach here. This frees each app/service from having to worry about the details of auth (the real gain). Feb 25, 2019 at 19:32
  • @king-side-slide I'm not sure if I follow... The authentication/authorization should be a single API where the user data is, but the session is regulated per application?
    – Gitnik
    Feb 26, 2019 at 9:05
  • Yes. That seems about right. Each app (App 1,2,3) maintains it's own "session" concept, and each uses the shared API to establish/validate this session. Feb 26, 2019 at 16:17

1 Answer 1

2

The real challenge here is how not to duplicate logic.

You need a single source of truth for what a user is, and what they can do. I've worked on systems before that accomplished this with a separate web app and web API, called something like the "Admin web app" or "user admin web app".

The other applications used a class library separate from the User Admin web application that only contained the logic to call the User Admin application and enforce permissions. This gives you a basic breakdown of "service provider" versus "consumer".

This architecture gives you the following components:

  • User Admin web API (service provider for Computers, also called upon by User Admin web app)
  • User class library (integrates Consumer and Service Provider web API)
  • Web app 1 (consumer, uses User class library to enforce permissions)
  • Web app 2 (consumer, uses User class library to enforce permissions)
  • Web app 3 (consumer, uses User class library to enforce permissions)
  • User Admin web app (service provider for Humans, probably also uses User class library to enforce permissions)

You'll have some code duplication between the Service Provider and User class library components, but it will be minimal. The main separation is read-only (consumers, User class library) versus read-write (User Admin web API, which should be called by User Admin web app).

5
  • Thank you! So, having back-end API server which contains everything about the user is ok. But, in order to avoid duplicating logic, I can implement a separate User API wrapper library that can be included into other apps (of course, this lib should hold logic to check user privileges - like helper permission-check decorators). If I follow you correctly? Is my proposed architecture ok then?
    – Gitnik
    Feb 26, 2019 at 9:09
  • Yes, you've got the main idea. The problem to solve is duplication of logic, not duplication of code. The helper library included by the other applications should not write back to the database or the User Admin web API. Only the User Admin web app should be making calls back to modify user information. The other apps should just be reading user data, not modifying it. Feb 26, 2019 at 13:12
  • Why not writing data? Is it to centralize the responsibility, in a sense that User Admin web app serves as a service that consumes User Admin web API in order to write data? Can you elaborate that? :)
    – Gitnik
    Feb 26, 2019 at 14:12
  • The reason to centralize the writing of the data, essentially, to the user admin web API is to simplify the class library included in all the other applications. If you make a change to how data is modified, you need to redeploy all the monoliths with the updated library. Or, you can redeploy the user admin web API and possibly only the user admin web application, which simplifies the deployment of business rule changes for how user information is managed. Feb 26, 2019 at 14:28
  • Ahh, thanks. That's really smart. I'll keep that in mind!
    – Gitnik
    Mar 4, 2019 at 9:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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