Question Summary
Hi Folks,
This is a kind of opinion question, I've built a Django library for my company and I keep swithering and changing my mind on how to structure it.
Possible strategies I've come up with are below:
Method 1 - Individual Libraries
Split all parts of the library into separate repos. For example my_library_core my_library_cookies my_library_exporter and include from them individually.
Pros
- Each library is compartmentalised and can be updated or included individually, so you can include only some of the functionality and install only some of the library modules.
Cons
- Dependencies / functionalities between libraries can get out of sync, if library one is using version 1 of the core library and library two is using version 2, you're forced to upgrade both to upgrade one.
- Lots of separate repos to keep on top of.
- Harder to have a reliable "core" library for common functionality.
- Feels messy / uncentralised.
Method 2 - Monolithic Library
Have one large library that contains all functionality.
Pros
- Centralised, everything is referencing the same library.
- Dependencies are centralised, the whole library has one set of dependencies that apply to all sub apps.
- Neater, everything imports from a one library.
Cons
- Upgrading the library would require potentially upgrading all the relevant host project dependencies to be in line with the library.
- Upgrading the library may mean changing any and all parts of the host project that refer to any sub apps of the library. So you couldn't just upgrade the "cookies" library, you'd need to upgrade ALL the references to the library.
- No "optional" libraries, it's all or nothing.
Method 3 - Monolithic with "contrib" apps
Much the same as the monolothic library except splitting optional apps into a contrib module.
Pros
- Can pick and choose included apps, don't need to include everything and therefore have fewer dependencies. For example if "pdf" library requires a third party library installed, but you don't use PDF, no need to install.
- Still allows for a single central library repo.
Cons
- Same as the monolithic library
- Slightly less neat code if importing from lots of nested sub apps.
- Decision whether functionality should be part of the 'core' parent app or separated into a sub app.
TLDR
My main question is, if you were going to make a reusable in-house python/django library to add extended functionality to be used on a large number of different projects, how would you best structure it and why?
Do the above methods and their pros/cons makes sense or is it just a case of picking one and sticking with it, where there is no ideal solution?
I'm currently building it in Method 3 but Method 1 also seems sensible. However I feel it would create maintenance problems with a lot of cross-checking between libraries to make sure they all work together. From a "neatness" point of view Method 1 also seems a bit gorey and you could end up with 20 separate library repos. Method 2 seems a bit too brute-force and means including a lot of extra functionality you may never use but potentially need to install dependencies for, same goes for Method 3 but you still have the issues of if you upgraded the version you'd need to update all code referencing the library.