Stop Writing CRUDy Apps
Podcast: Play in new window | Download (49.7MB) | Embed
Subscribe: Apple Podcasts | Spotify | Email | RSS | More
“A database object is not a programming object.”
CRUD stands for Create, Read, Update, Delete. These are the major functions you’ll see in database applications. CRUD functions are user interfaces to databases. CRUD manipulates entities in a database. Functions talking to the database manipulate data in the tables. Each letter in CRUD can be associated with relational databases (SQL Statements), HTTP methods, or DDS operations.
“The map is not the path.”
CRUD in and of itself isn’t bad. Most of the problems we list are process related. There are few technical problems in the list. They are more about misuse. CRUD is a way of conceptualizing the relationship of how data is stored and transferred.
Episode Breakdown
11:52 It’s Boring
“You miss stuff because you’re doing the same thing repetitively.”
Typically repetitive as once you solve it you are doing it over and over for all data stored. This is why ORMs and other automation tools are used. Automation tools have their own issues. Apps are different and have different uses and flows. Tools can add complexity by trying to be omni-purposed.
There is not an easy solution to boredom when the task needs to get done. Find an automation tool that allows customization. Try to batch building CRUD pieces of the application. Use the DRY principle as much as possible. Create templates or boilerplate code where possible. This has it’s own set of problems. You have to be careful to not become too reliant on the templates. Use them for to avoid tedium not actual development.
19:40 Direct Table Access
This restricts what other people using the database can do. Which makes other people want to restrict you. This can also have interesting security implications in some cases, as you may not want your app to be able to update all columns in the first place. Use an in-database abstraction like a view or stored procedure.
21:27 Changes to DB Require Changes to Your View
“The problem is WHEN it happens.”
This makes your application fragile with respect to something that is outside of its control. Since DBAs are often under a completely different chain of command, this can also make the way you implement your code subject to the results of corporate infighting.
“This is a situation that development rarely wins.”
Make specific DB abstractions per task so that you only have to change the ones that you actually need to change.
24:03 Doesn’t Reflect Reality
“I didn’t check a box that says hasBeard, I just didn’t shave.”
You don’t update your person record, you move, get married, etc. This pushes you towards bending the world toward your software, rather than in the other direction.
“The world is a lot bigger than your database, no matter what Big Data says.”
Express things in terms of entities, and operations on those entities, then figure out how to project those into a datastore and retrieve them from it.
29:33 Entities Are Constrained To What The Database Understands
This can force the design decisions you make to look illogical to your stakeholders. Things like inheritance, polymorphic relationships, and heirarchical relationships are harder to represent in a relational database. Developers designing that way will avoid using them when it makes sense to try and avoid the headache. This can easily bleed all the way into the UI layer and make it painful for your users.
“You end up expressing thing in terms that the business users don’t understand.”
Build the object model and store to a document database or some other non-relational store, then figure out your underlying data model later.
36:23 Development Timelines
“That’s one of the dangers of prototyping with live code.”
Because you can stand up a simple crud form with a code generator in a few minutes, it will be expected of you when you can’t. CRUD approaches and the automation that goes with them form a sort of moral hazard. If it works for one situation, you’ll try to make it work for a more complex one, until you find out you can’t, usually after a lot of trying.
You can still do CRUD, but you have to communicate that the approach ONLY works for very simple scenarios and can’t be bent to work for more complex ones. Even if you can bend a code generator a little you probably shouldn’t because now they are going to be trying to convince you that you can bend it further, rather than accepting that you can’t.
41:10 Estimations After The Fact
A year after a CRUD app is put into production, a change request comes in. Your developer makes an estimate on fixing it, based upon reasonable assumptions about the app. The CRUD model can confound this. Long-maintained CRUD apps with lots of changes eventually devolve into a raft of hacks, even though they still look like CRUD apps.
Use CRUD or don’t. But don’t use CRUD and try to bend it into something it isn’t. This is politically difficult when someone is looking at an app that mostly works and they want “one little tweak”. The real solution is not to use CRUD if you think that might happen.
IoTease: Project
IOT Alcohol & Health Monitoring System
This would be an interesting project if it were designed for home or personal use but the description talks about using this to determine if employees are under the influence of alcohol or “under bad health conditions”. While you shouldn’t be drinking on the job there are a lot of ethical problems with this concept. First off for “bad health conditions” all it does is monitor blood pressure. While that can give a fair amount of information it is merely a snapshot. Next who is monitoring this? Is it a licensed physician determining a person is too “unhealthy” to work? Lots of poor assumptions and implications here. As for the alcohol monitoring all it says is “Alcohol Sensor” which is not specific enough.
Tricks of the Trade
Be aware of the limits of your ability to optimize for preventing problems in the way users use your system. Hit the low-hanging fruit and the really damaging problems for sure, but try to make it so that you can manually fix less frequent or less damaging problems, rather than trying to build the fix into your app. Not only will it make it easier to ship, but less frequent problems are harder to predict (and harder to predict the frequency of) than more common, obvious ones. This lets you get a release out and then determine triage processes, rather than assuming you know what problems will happen the most. Your users can do dumb things far longer than you can stay sane trying to keep them from doing dumb stuff, so plan accordingly.