Naming is hard but important
The hardest thing in programming?
The beginning of wisdom is to call things by their proper name <br>*- Confucius*
Disambiguation
- Page endpoint: Endpoint serving
htmlHTTP response
- API endpoint: Endpoint serving
json/xml/html partialHTTP response
Directory structure similar to tab vs space is an "unsolvable problem". It always raises incessant debates that emphasize personal preferences while neglecting about what's the problem to solve. In general, there're 2 popular ways of doing this, i.e. grouping by file types (functionality) or grouping by features. Or if you embrace minimalism, a single index.php can be a reasonable choice as well.
In fact, what's more important might be how you decide to name stuff. Naming is hard, probably the hardest thing in software engineering. I get confused when seeing directory structure like this.

I have no question about storage or util since they fall under the βgrouping by file typesβ category, but everything under the web/** isn't as clear as above. There're 3 terms "web", "api" and "handler" each may have very different meaning under different context. In combining "web" with "handler", I got "web handler" (a.k.a "controllers") which is self explanatory. But how about "web api" (Web API??) and "web webapi"?
After working with the codebase for a while, I eventually figure out that all stuffs within the web folder are web handlers for different purposes. i.e. web/handler is for page endpoint, web/api for api endpoint, web/webapi for api endpoint only accessed by browser or mobile. It's clear that this isn't an <span color="green_bg">idiomatic</span> way of naming things and professionals can do better than that. But how could it be named like this? Obviously there're some background stories.
- One of them is migration. Migrating from monolithic web applications to service-oriented architecture (data layer), as well as from multiple page app to single page app (presentation layer) usually happens side by side, this is what's causing above [Page endpoints](/d1c11be2cf564bc8ad597d8c509e9056?pvs=25) to be turned into a hybrid of Page and [API endpoints](/d1c11be2cf564bc8ad597d8c509e9056?pvs=25).
- Then there's the pressure of getting things done. Everyone knows that business values velocity, and it's not a bad thing. Especially for tasks with little to none return of investment like migration, the rush to get it done and move into the next more interesting stuff is very tentative (I'm in the same group π
). However, if we can zoom out a bit and evaluate the cost of time wasted to understand and maintain code full of arbitrary names, we might be willing to put a few extra minutes going through list like this and come up with more thoughtful names instead
- Also, people tend to assume others understand their assumptions. Itβs a common cognitive bias called curse of knowledge. E.g. in naming the folder as "web/webapi", there is an assumption that the API is browser/mobile facing is a shared consensus, while I can't see why the same thing can't be applied to "web/api" either. Simple changes like below will help clarify this a lot
```plain text
βββ handlers
βββ page
βββ api
βΒ Β βββ protected
```
You might ask "what would be the idiomatic way of doing this then?" Let's turn to the community for some inspiration, since it's usually smart not to reinvent the wheel unless for "good" reason. Use two convention over configuration web frameworks as example.
<details>
<summary>The Rails (Ruby) skeleton</summary>
```plain text
βββ Gemfile
βββ Gemfile.lock
βββ README.md
βββ Rakefile
βββ app
βββ assets
βΒ Β βββ config
βΒ Β βββ images
βΒ Β βββ stylesheets
βββ channels
βΒ Β βββ application_cable
βββ controllers
βΒ Β βββ application_controller.rb
βΒ Β βββ concerns
βββ helpers
βΒ Β βββ application_helper.rb
βββ javascript
βΒ Β βββ channels
βΒ Β βββ packs
βββ jobs
βΒ Β βββ application_job.rb
βββ mailers
βΒ Β βββ application_mailer.rb
βββ models
βΒ Β βββ application_record.rb
βΒ Β βββ concerns
βββ views
βββ layouts
βββ babel.config.js
βββ bin
βββ config
βββ config.ru
βββ db
βββ lib
βββ log
βββ node_modules
βββ package.json
βββ postcss.config.js
βββ public
βββ storage
βββ test
βββ tmp
βββ vendor
βββ yarn.lock
```
</details>
<details>
<summary>The Phoenix (Elixir) skeleton</summary>
```plain text
βββ _build
βββ assets
βββ config
βββ deps
βββ lib
β βββ hello
β βββ hello.ex
β βββ hello_web
βββ controllers
βΒ Β βββ page_controller.ex
βββ templates
βΒ Β βββ layout
βΒ Β βΒ Β βββ app.html.heex
βΒ Β βΒ Β βββ live.html.heex
βΒ Β βΒ Β βββ root.html.heex
βΒ Β βββ page
βΒ Β βββ index.html.heex
βββ views
βΒ Β βββ error_helpers.ex
βΒ Β βββ error_view.ex
βΒ Β βββ layout_view.ex
βΒ Β βββ page_view.ex
βββ endpoint.ex
βββ gettext.ex
βββ router.ex
βββ telemetry.ex
β βββ hello_web.ex
βββ priv
βββ test
```
</details>
Not to say they are the best practice to follow, but generic terms like "web" and "api" are either avoided or used with caution, plus we can always fallback to google for more detailed explanations thanks to their popularity.
Comments