2

I need to make an app for employees & employers.

When is it worth writing your own CRUD generator for a project with the aim of process automation?

With such a generator I wouldn’t need to create manually basic CRUD models, for example: job type, countries, cities, male, work experience, education, especially when considering than in future there might be a much more models.

I wonder if this a bad idea, cause it looks like an "overengineering".

And if it's worth the effort, what should I be aware of?

Some additional info: Backend is PHP + Laravel; Frontend is JS + Vue.js

3
  • Oblig XKCD: xkcd.com/1319 Jun 10, 2022 at 23:57
  • And also xkcd.com/1205 Jun 10, 2022 at 23:59
  • And I see XKCD 1205 had been referenced by 2 answers and 1 comment! It is a silly and very good guide when determining whether or not to invest time building a tool. Jun 11, 2022 at 0:05

4 Answers 4

5

It's typically not a good idea to build a framework/generator. Common issues with such an approach include:

  • Debugging is more difficult than with straightforward code.

  • Leaky abstractions: your tooling might handle the easy, common cases. But how will you deal with the more tricky requirements that your generator cannot handle? It is difficult to design your tooling well to leave enough extensions points.

  • Inner-platform effect: if your generator is in fact sufficiently configurable to handle all the real-world nuances, then its complexity is approaching the programming languages you're trying to replace.

  • YAGNI: if you build a generator up front, it is likely that you will spend time on features that you don't actually need

  • It doesn't save that much time. If your CRUD models are easy to automate, there's also a good chance they're easy to create by hand (even if that's boring). Sometimes, automation simply isn't a good business decision (compare xkcd 1205).

What to do instead:

  • Start by writing things by hand.
  • As you notice shared behaviour and repeated patterns, think about how you can extract these patterns in a reusable manner. Refactor existing code bases accordingly.
  • Eventually, you'll have a library of reusable parts. This will simplify maintenance (only have to update/fix things in one place) and will speed up programming of future additions.
  • You might not be the first one to do this. Maybe there are existing packages or libraries providing some or all of the features you need.
    • In particular, ORMs can typically simplify common CRUD tasks a lot.
3

If you are considering a generator, you probably have already written some CRUDS manually. And I understand your code of honor: “Never do yourself what a machine could do for you”.

It will all depend on the cost and the benefits:

  • If you have so many more CRUDs to write that it’s faster to write a generator, go for the generator. Economically speaking, it could be a saving.
  • If you are in a business where you’ll have plenty if CRUD requirements in the future and your generator could generate OCP compliant code to deal with future requirements as well, then go for the generator. Economically speaking, it would be an investment.
  • If you’ll be so happy with your successful generator, you could one day consider going into the tooling/generator market. Economically speaking, it’d be diversification.

However, don’t forget that once you have generated those 2000 CRUDs and thousand s of lines of code, you’ll have to maintain them. So better get your generator right. And here lies the risk: that in the end it’ll appear much more time consuming than initially expected, ruining your hopes and jeopardizing your project.

There’s a middle way with far less risks: make some good design for your generic CRUD code and write a couple of simple macros for your favouride editor/IDE ;-)

2
  • 3
    "However, don’t forget that once you have generated those 2000 CRUDs and thousand s of lines of code, you’ll have to maintain them. So better get your generator right." This problem is no worse for one-time generated code than it is for hand-written code. But, if you can edit the generator and re-generate, this is actually a strength and not a weakness. Jun 10, 2022 at 15:41
  • 1
    @TheRubberDuck Yes. I think we agree. Your argument reinforces my point on getting the generator right. Because if you don’t, you’ll end up fine tuning the generated code by hand. And if you the regenerate, you’d lose the tuning. So the only way is to have a design and a generator that is robust enough and allows you to cope with all the domain specific behavior (e.g. constraint enforcement, validation, updating of dependent objects if necessry, etc…). Nothing impossible, but probably more complex than just parse a template file and make some substitutions ;-)
    – Christophe
    Jun 10, 2022 at 17:41
1

First, know what you're getting.

I've wasted a lot of time on bad code generation tools, as well as on trying to extract "reusable" components from unrelated units of code based on apparent similarity. The biggest piece of advice I can give is: don't overgeneralize. It's easy to see a pattern and expect it to apply forever when that really isn't the case. What do you do when some of your CRUD entities need to have unique names and others don't, or when you need to account for unique relationships between them (e.g, a city is inside a a country)?

Be prepared to run into situations that will utterly break your script. Then you will either have to hack in conditionals to support them, rework the design to make fewer assumptions, or just leave that scenario unsupported.

A second piece of advice that follows from that: don't depend on it. Because codegen can so easily fail to deliver, be prepared to do without. There are two main ways I've used codegen:

  1. As a starting point — run it whenever you want, then adjust whatever doesn't fit the requirements. This is cheap and relatively safe because you're not stuck with anything. It doesn't have to solve the whole problem, but just most of the boring stuff up-front.

  2. To replace manual development — This is much more powerful, and thus much more dangerous. In this paradigm, you never modify generated files but instead modify the logic/templates and the inputs to them and re-generate the files. You really need to be prepared to test and retest everything thoroughly whenever you re-generate files, because an innocent change for the sake of one CRUD entity can wreak havoc on others.

Again, don't depend on it: be very ready to "fall back" to manually maintaining the code rather than trying to account for every edge case. You can start each case off as option #2 and then effectively switch to #1 the moment you run into trouble: don't ever generate that code again, instead only adjust by hand.

Then, weigh it against the alternative.

Codegen is only good for cases where the result is highly mechanical — where you're more likely to make a mistake because the mindless repetition is putting you to sleep than because there was a flaw in the logic. In that case, encode that formulaic task

At the end of the day, it's a cost/benefit decision. You have to look at how much you're repeating yourself and how easily that repetition can be scripted. Like in the link @amon made to the relevant XKCD, try to estimate how much time you would save vs. how much time it will take to write.

But, do realize that you will spend a lot of time creating and adjusting your codegen code. It's never as simple as you'd expect, and there's always an edge case you haven't considered. I've saved a lot of time by writing code generators, but I've wasted a lot, too.

0

It is almost never a good idea to write your own generator - unless writing generators is your main job. There are so many gotchas that unless you are doing just that - don't do it.

Your project looks small enough - to write the CRUDs by hand. That is the first recommendation. But, if you want to automate it I would recommend https://quickadminpanel.com/ for PHP-Laravel.

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