Laravel-ൽ Event-Driven Decoupling മാസ്റ്റർ ചെയ്യാം

നിങ്ങളുടെ Laravel കൺട്രോളറുകൾ പലപ്പോഴും ബിസിനസ് ലോജിക്കുകൾ (business logic) കുത്തിനിറയ്ക്കുന്ന ഇടങ്ങളായി മാറുന്നു.

നിങ്ങൾ ഒരു ലളിതമായ രജിസ്ട്രേഷൻ ഫ്ലോയിൽ നിന്നാണ് തുടങ്ങുന്നത്. എന്നാൽ ഉടൻ തന്നെ, ഇമെയിൽ നോട്ടിഫിക്കേഷനുകൾ, Slack അലേർട്ടുകൾ, ഓഡിറ്റ് ലോഗുകൾ, API കോളുകൾ എന്നിവയെല്ലാം ഒരൊറ്റ മെത്തേഡിലേക്ക് നിങ്ങൾ ചേർക്കുന്നു. ഇത് ഒരു fat controller ഉണ്ടാക്കുന്നു.

Fat controllers നിങ്ങളുടെ കോഡിനെ ദുർബലമാക്കുന്നു. അവ ടെസ്റ്റ് ചെയ്യാൻ പ്രയാസമാണ്. അവ Single Responsibility Principle ലംഘിക്കുന്നു.

ഇത് പരിഹരിക്കാൻ RabbitMQ പോലുള്ള സങ്കീർണ്ണമായ ടൂളുകൾ നിങ്ങൾക്ക് ആവശ്യമില്ല. മിക്ക ആവശ്യങ്ങൾക്കും അനുയോജ്യമായ ഒരു ഇൻ-ബിൽറ്റ് ഇവന്റ് സിസ്റ്റം Laravel-ൽ ലഭ്യമാണ്.

Tight coupling-ലെ പ്രശ്നങ്ങൾ:

  • ഒരു ന്യൂസ്‌ലെറ്റർ API സാവധാനത്തിലാണെങ്കിൽ, നിങ്ങളുടെ യൂസർ രജിസ്ട്രേഷനും സാവധാനത്തിലാകും.
  • ഒരു മെയിൽ സർവീസ് പരാജയപ്പെട്ടാൽ, മുഴുവൻ റിക്വസ്റ്റും പരാജയപ്പെടുന്നു.

പരിഹാരം: Event-Driven Architecture.

ഇവന്റുകൾ ഒരു മിഡിൽ ലെയർ (middle layer) ആയി പ്രവർത്തിക്കുന്നു. നിങ്ങളുടെ കൺട്രോളർ ഒരു ആക്ഷൻ പ്രഖ്യാപിക്കുന്നു. ലിസണറുകൾ (Listeners) ആ ആക്ഷനോട് സ്വതന്ത്രമായി പ്രതികരിക്കുന്നു.

ഒരു ലീൻ (lean) കൺട്രോളർ ഇപ്രകാരമായിരിക്കും:

public function register(RegisterRequest $request)
{
    $user = User::create($request->validated());

    UserRegistered::dispatch($user);

    return response()->json(['message' => 'Success'], 201);
}

കൺട്രോളർ ഇപ്പോൾ ഡാറ്റാ പെർസിസ്റ്റൻസ് (data persistence) മാത്രമേ കൈകാര്യം ചെയ്യുന്നുള്ളൂ. സൈഡ് ഇഫക്റ്റുകളെ (side effects) കുറിച്ച് അത് ശ്രദ്ധിക്കുന്നില്ല.

നിങ്ങൾക്ക് മൂന്ന് പ്രധാന നേട്ടങ്ങൾ ലഭിക്കുന്നു:

  • പെർഫോമൻസ് (Performance): ഉപയോക്താക്കൾക്ക് ഉടൻ തന്നെ റെസ്പോൺസ് ലഭിക്കുന്നു. കനത്ത ജോലികൾ (Heavy tasks) ShouldQueue ഇന്റർഫേസ് ഉപയോഗിച്ച് ബാക്ക്ഗ്രൗണ്ടിൽ പ്രവർത്തിക്കുന്നു.
  • റെസിലിയൻസ് (Resilience): ഒരു സർവീസ് പ്രവർത്തനരഹിതമാണെങ്കിൽ പോലും, മെയിൻ ആപ്ലിക്കേഷൻ തകരാതെ തന്നെ ലിസണറിന് ആ ജോലി വീണ്ടും ചെയ്യാൻ (retry) സാധിക്കും.
  • എക്സ്റ്റൻസിബിലിറ്റി (Extensibility): ഒരു പുതിയ ലിസണർ ചേർക്കുന്നതിലൂടെ പുഷ് നോട്ടിഫിക്കേഷനുകൾ പോലുള്ള പുതിയ ഫീച്ചറുകൾ നിങ്ങൾക്ക് ചേർക്കാൻ കഴിയും. ഇതിനായി ഒറിജിനൽ കൺട്രോളറിൽ മാറ്റം വരുത്തേണ്ടതില്ല.

പിന്തുടരേണ്ട മികച്ച രീതികൾ (Best practices):

  • സൈഡ് ഇഫക്റ്റുകളിൽ ശ്രദ്ധ കേന്ദ്രീകരിക്കുക: പോസ്റ്റ്-പ്രോസസ്സിംഗിനായി (post-processing) ഇവന്റുകൾ ഉപയോഗിക്കുക. ഉടൻ തന്നെ നടക്കേണ്ട പ്രധാന ലോജിക്കിനായി ഇവ ഉപയോഗിക്കരുത്.
  • വിവരണാത്മകമായ പേരുകൾ ഉപയോഗിക്കുക: OrderPlaced അല്ലെങ്കിൽ UserRegistered പോലുള്ള പാസ്റ്റ് ടെൻസ് (past-tense) പേരുകൾ ഉപയോഗിക്കുക. ഇത് ആ ആക്ഷൻ നടന്നുവെന്ന് സൂചിപ്പിക്കുന്നു.
  • അമിതമായ അബ്‌സ്‌ട്രാക്ഷൻ (over-abstraction) ഒഴിവാക്കുക: ഒരു കോഡ് ലളിതമാണെങ്കിൽ അവ ഒരിടത്ത് മാത്രമേ ഉപയോഗിക്കുന്നുള്ളൂ എങ്കിൽ, ഒരു ഇവന്റിനേക്കാൾ ഒരു ഫംഗ്ഷൻ കോൾ ആണ് നല്ലത്.

ഡാറ്റാബേസ് മാറ്റങ്ങൾക്കായി Eloquent Observers ഉപയോഗിക്കുക. ബിസിനസ് ആക്ഷനുകൾക്കായി ഇവന്റുകൾ ഉപയോഗിക്കുക.

ഇവന്റുകളിലേക്ക് റീഫാക്ടർ ചെയ്യുന്നത് കോഡിന്റെ ഈടുനിൽപ്പിന് (durability) വേണ്ടിയാണ്. ഇത് നിങ്ങളുടെ കോഡ് ഡീബഗ് ചെയ്യാനും ടെസ്റ്റ് ചെയ്യാനും എളുപ്പമാക്കുന്നു.

നിങ്ങളുടെ കൺട്രോളറിലെ അമിതമായി ലോഡ് നൽകുന്ന ഒരു സൈഡ് ഇഫക്റ്റ് ഇന്ന് തന്നെ തിരഞ്ഞെടുത്ത് ഒരു ലിസണറിലേക്ക് മാറ്റുക.

ഈ സാൻഡ്ബോക്സ് ഉദാഹരണം പരീക്ഷിച്ചു നോക്കൂ: https://onlinephp.io/c/1f7b2

Source: https://dev.to/codecraft_diary_3d13677fb/beyond-fat-controllers-mastering-event-driven-decoupling-in-laravel-2dd6