Misuse of MVC Architecture in Production

2017-12-21 11:33Edit this page

I have an external-facing API that uses the Mojolicious framework, mainly implementing some general and customer-customized requirements. As requirements kept increasing, it became bloated and unwieldy. Here I’ll analyze it as a negative example. The general design structure is as follows:

api=>start: API
route=>condition: Route
common_route=>subroutine: Common Route
custom_route=>subroutine: Custom Route
common_controller=>condition: Common Controller
custom_controller=>subroutine: Custom Controller
hacked_code=>operation: hacked code
hacked_middleware=>operation: hacked middleware
common_io=>inputoutput: Common io/db process
hacked_user_io=>inputoutput: Hacked io/db process
render=>end: Render

api->route(no)->custom_route->custom_controller->render
api->route(yes)->common_route->common_controller->common_io->render
api->route(yes)->common_route->common_controller(no)->hacked_code->hacked_user_io->render
api->route(yes)->common_route->common_controller(yes)->hacked_middleware->hacked_user_io->render

I haven’t drawn the Model part of this structure here, because it’s also a mess.

Let me briefly explain this misused structure.

Ideal

Routes are mainly divided into two parts: one for common feature API routes, and one for customer-customized API routes. This is the ideal situation: when customers don’t have customization needs, they just use the common route’s API; when customization is needed, new paths are added separately in the custom routes.

Reality

In practice, I found this isn’t really a universal solution. Because some customers using the common API sometimes have customization needs, such as:

  • During POST operations, instead of calling the common random function to generate strings, use customer-customized rules to generate strings before database operations. So I added ugly uid judgment logic in the code - if conditions are met, perform operation A, otherwise perform the common operation. After multiple similar code hacks, I added a middleware for uid judgment, but it’s still ugly.
  • In the Common Route section, there’s an authentication middleware to ensure legitimacy. Here again, there are customer-customized authentication schemes to implement.
  • In customer-customized features, there might be new data to store, so I would create new tables or fields in the Model, but these customized fields can’t have good access control.

In summary, in this architecture, some modules or structures were fixed at design time, but in actual use, almost every module is required to be customizable and replaceable (at the user level).

Solution (To be continued)

Unless otherwise stated, articles on this blog are licensed under the Creative Commons Attribution 4.0 International License. Please credit the original author and source when sharing.


Tags: web

No comments yet

Leave a comment

Creative Commons © 2013 — 2026 xiaocang | Theme based on fzheng.me & NexT | Hosted by Netlify