My application uses 3 types of User : Students, Teachers & Admins.
The User base class serves as a mechanism for authentication, and I’ve decided for this project to use apikeys (note : it’s a demo project).
Hence, there’s an Apikey entity (living in its own table) and the User base class has a OneToOne mapping to a single Apikey.
I’m using mapped superclasses, so my database will contain four tables :
- instructor
- admin
- student
- apikey
In my registration process, apikeys are created, and a verification must be done to ensure no two apikeys exist with the same token. The table is annotated with a “unique” constraint but I want to perform this verification as well in my application services layer.
For that, I’d need an Apikey repository to verify that the apikey I’ve created (through a random generator) is indeed unique. But Apikey is an entity, and it’s common wisdom not to create repository for entities as that may violate the consistency boundary of the aggregate.
And I can’t make Apikey an Aggregate itself, because it makes no sense for an Apikey to exist outside of an Instructor/Admin/Student. An apikey necessarily belongs to either of these users.
So my questions are :
- Is it fine to create a repository for apikeys in this case ? Are there any negative consequences to that design ?
- Or should I embed a
findByApikey
method in each repository (InstructorRepository, AdminRepository, StudentRepository), and have my ApikeyGeneratorService depends on these three repository, and add one methodgenerateApikeyFor(Student|Admin|Teacher)
for each specific use case ? That seems very redundant. - Or should I create a root
UserRepository
with a single methodisApikeyAvailable
? That repository would have no other purpose because User is an abstract class and there’s no “User” in existence per se.
Note that I absolutely want to perform this verification in my code for this particular project.