Hacker News new | ask | show | jobs
by egeozcan 597 days ago
From my experience, these frameworks are like the express lane for kicking off a project because there are no big decisions to make. But once you’re knee-deep in Rails, Django, or Laravel and need to do something off the beaten path, things can get dicey. Why? Because you didn’t write the glue code yourself, so there's a gap in understanding, not really a technical roadblock (most of the time!). My point is, if you dive into these frameworks and actually learn the guts, you'll save yourself tons of time coding by, well, reading code.

Now, do I actually do this? Absolutely not. Rewriting everything is way too much fun, and I live for the thrill of trying new things, even if it makes zero business sense.

2 comments

When I first learnt Django I sometimes felt like that, but I actually found the source code for it and DRF to be very readable, to the point that it's very obvious where they expect you to step outside the guardrails.
As a personal anecdote,I have not at all found this for drf. I personally dread every time something goes wrong in our api code, it's a sea of overcomplicated inheritance trees (some of this is our fault, but it's at drfs direction imo) and factors that eventually just end up with me never being able to find where anything actually happens, other than via a mountain of print statements.

Django by contrast, I agree, it's perfectly clear. (Though some of the meta magic does get spooky, but that's the nature of meta magic, and I generally find the tradeoffs are worth it)

I liked https://www.cdrf.co/ for exploring DRF.

You basically have either a property or a function with the name get_property for a certain number of things (queryset, serialiser, pagination class, etc.) in any case. I tend to recommend in our projects style guides that once you want to override the behaviour of a mixin, you don’t inherit from the mixin anymore.

The two biggest issues I came across with teams in DRF were people coupling the serialised directly to a single database model (i.e. using ModelSerializer everywhere, even when that didn’t make sense), and trying to put too much stuff into a single class based view or viewset.

I find DRF has a lot of places where someone can alter the behavior of handling the request, which can make it really hard to track down where some field or behavior is coming from. You can define methods on the view, serializer, model, or filter (or some superclass of these) to totally change how some response is formed. It is very flexible, and can save a lot of typing if you have all the conventions in your head (and everybody working on a project strictly follows the same conventions). But I find plain Django or something like Flask much easier to grok.
What’s an example of a feature for a Laravel site where not fully understanding the mechanisms of Laravel under the hood would make that existing code get in the way of building the new feature? Genuine question.
Luckily I have a real life example from a customer project I was involved as a consultant: Integrating a custom identity provider with multi-factor authentication. This was from many years ago though. They also used to have some performance problems in some naively implemented middleware and needed to deep-dive into how things actually work before being able to optimize. And commands - I was doing the integration with our software and their command queue was always causing problems with stuck jobs until they read the implementation. The specific problem with Laravel as a product is (was?) that the docs are too beginner oriented and perhaps "you don't need to know what's under the hood" mindset is exactly what's causing this. I got to know many experienced PHP developers who got really frustrated because of the ELI5 style docs.

You can't always rely on the docs too, however excellent they may be - some game developers read code from game engines to optimize, some web developers read code from their web frameworks. But, some change their whole stack when they get frustrated, and I argue that it makes little to no business sense to do so. Just understand what you are working with and deeply.

I can't speak for the other frameworks, but with Django this would have not been a problem at all. In Django, most "batteries included" features really just are 1st party plugins, i.e. you can choose to not use the builtin authentication stack and bring your own. All of this is officially supported and well documented, e.g. https://docs.djangoproject.com/en/5.1/topics/auth/customizin...