লারাভেল অ্যাপে বৈশিষ্ট্যগুলি সক্ষম / অক্ষম করা


10

আমি একটি লারাভেল অ্যাপ তৈরি করছি, যার বিভিন্ন বৈশিষ্ট্য রয়েছে। আমি একটি নির্দিষ্ট ডোমেনের প্রয়োজনের উপর নির্ভর করে এগুলি সক্ষম বা অক্ষম করতে সক্ষম হতে চাই। বর্তমানে, আমি আমার কনফিগারেশে কয়েকটি সিরিজের পতাকা রয়েছে:

'is_feature_1_enabled' => true,
'is_feature_2_enabled' => false,

... ইত্যাদি।

তারপরে আমার নিয়ন্ত্রক এবং দর্শনগুলিতে, আমি কিছু কনফিগার করার অনুমতি দিচ্ছি, আমার কিছু প্রদর্শন করা উচিত কিনা তা দেখার জন্য আমি এই কনফিগার মানগুলি পরীক্ষা করে দেখি app

লারাভেল অ্যাপে বৈশিষ্ট্যগুলি পরিচালনা করার জন্য কি সর্বোত্তম অনুশীলন পদ্ধতি আছে?


নিয়ামক পরিবর্তে রুট অক্ষম? বা মিডলওয়্যার সম্ভবত ব্যবহার করতে পারেন
বার্তো 99

বৈশিষ্ট্য! == পৃষ্ঠা
স্ট্যাকওভারফ্লো নিউবিবি


আসলে একটি সমাধান হতে পারে। একটি উত্তর হিসাবে আপনার মন্তব্য করতে চান?
স্ট্যাকওভারফ্লো নিউবিবি

মিঃ কোনও সমস্যা নেই, কোনও উত্তর নয়, গুরুত্বপূর্ণটি এটি আপনাকে সহায়তা করতে পারে
বার্তো৯৯

উত্তর:


4

একে প্রযুক্তিগতভাবে বৈশিষ্ট্য পতাকা বলা হয় - https://martinfowler.com/articles/feature-toggles.html

আপনার প্রয়োজনীয়তা, কনফিগারেশন / ডাটাবেস, রোলআউট ইত্যাদির উপর নির্ভর করে ...

তবে এটি মূলত যদি কোডে থাকে এবং পরিষ্কার হতে পারে না।

ল্যারাভেল প্যাকেজ:

https://github.com/alfred-nutile-inc/laravel-feature-flag

https://github.com/francescomalatesta/laravel-feature

কিছু পরিষেবা:

https://launchdarkly.com/

https://bullet-train.io/

https://configcat.com/

ফ্রন্টএন্ডের জন্য https://marketingplatform.google.com/about/optimize/ এ দেখুন ।


1
বৈশিষ্ট্যটি পতাকাঙ্কিত করে আপনি এখানে একটি নমুনা লারাভেল
পিটার

7

আমি একাধিক হোটেল সরবরাহকারীকে বাস্তবায়নের চেষ্টা করার সময় আমি একই সমস্যার মুখোমুখি হয়েছি।

আমি যা করেছি তা ছিল পরিষেবা কন্টেইনার ব্যবহার করা।

প্রথমে আপনি প্রতিটি ডোমেনের জন্য তাঁর বৈশিষ্ট্য সহ শ্রেণি তৈরি করবেন:

  • Doman1.php, Domain2.php এর মত
  • তারপরে প্রত্যেকের ভিতরে আপনি নিজের যুক্তি যুক্ত করবেন।

তারপরে আপনি ক্লাসের সাথে ক্লাসের সাথে ডোমেন বাঁধতে আপনার অ্যাপ্লিকেশন পরিষেবা সরবরাহকারীর মধ্যে বাইন্ডিং ব্যবহার করবেন।

$this->app->bind('Domain1',function (){
       return new Domain1();
    });
    $this->app->bind('Domain2',function (){
        return new Domain2();
    });

নোট আপনি সাধারণ ক্লাসটি ব্যবহার করতে পারেন যা বৈশিষ্ট্যগুলি সমস্ত ডোমেনের সাথে চলে তারপরে সেই ক্লাসটি আপনার ক্লাসে ব্যবহার করতে পারেন

অবশেষে আপনার নিয়ামক আপনি নিজের ডোমেনটি পরীক্ষা করতে পারেন তারপরে আপনি যে ক্লাসটি ব্যবহার করছেন তা ব্যবহার করতে পারেন

    app(url('/'))->methodName();

0

মনে হচ্ছে আপনি নির্দিষ্ট বৈশিষ্ট্য সক্ষম বা অক্ষম করতে কনফিগার মানগুলির উপর ভিত্তি করে জিনিসগুলি কোডিং করছেন। আমি আপনাকে কনফিগার মানের পরিবর্তে নামযুক্ত রুটের ভিত্তিতে জিনিসগুলি নিয়ন্ত্রণ করার পরামর্শ দিচ্ছি।

  1. সম্পূর্ণ বা বৈশিষ্ট্য অনুসারে সমস্ত রুটকে গোষ্ঠীভুক্ত করুন।
  2. সমস্ত রুটের নাম নির্ধারণ করুন
  3. ডেটাবেজে রুটের নাম এবং রেকর্ড দ্বারা সক্ষম / অক্ষম করা কার্যকলাপ নিয়ন্ত্রণ করুন
  4. অনুরোধ অবজেক্ট থেকে বর্তমান রুটের নাম পেয়ে এবং এটি ডেটাবেসটির সাথে মিলে কোনও নির্দিষ্ট বৈশিষ্ট্য সক্ষম বা অক্ষম করা হয়েছে কিনা তা পরীক্ষা করতে লারাভেল মিডলওয়্যারটি ব্যবহার করুন ..

সুতরাং আপনার যেখানে যেখানেই পুনরাবৃত্তি হবে এবং আপনার কোডটি ফুটিয়ে তুলবে একই শর্ত আপনার হবে না .. এখানে একটি নমুনা কোড রয়েছে যা আপনাকে সমস্ত রুটগুলি কীভাবে পুনরুদ্ধার করতে হবে তা দেখায় এবং আপনার অবস্থার সাথে সামঞ্জস্য করার জন্য আপনি রুট গ্রুপের নামের সাথে আরও প্রক্রিয়া করতে পারেন।

Route::get('routes', function() {
$routeCollection = Route::getRoutes();

echo "<table >";
    echo "<tr>";
        echo "<td width='10%'><h4>HTTP Method</h4></td>";
        echo "<td width='10%'><h4>Route</h4></td>";
        echo "<td width='80%'><h4>Corresponding Action</h4></td>";
    echo "</tr>";
    foreach ($routeCollection as $value) {
        echo "<tr>";
            echo "<td>" . $value->getMethods()[0] . "</td>";
            echo "<td>" . $value->getPath() . "</td>";
            echo "<td>" . $value->getName() . "</td>";
        echo "</tr>";
    }
echo "</table>";
});

এবং এখানে একটি নমুনা মিডলওয়্যার হ্যান্ডলার রয়েছে যেখানে আপনি ইতিমধ্যে আপনার ডেটাবেজে সঞ্চিত যা আছে তার সাথে মিল রেখে কোনও নির্দিষ্ট বৈশিষ্ট্য সক্রিয় রয়েছে কিনা তা আপনি পরীক্ষা করতে পারবেন ..

public function handle($request, Closure $next)
    {
        if(Helper::isDisabled($request->route()->getName())){
             abort(403,'This feature is disabled.');
        }
        return $next($request);
    }

1
এটি ধরে নিয়েছে যে বৈশিষ্ট্যগুলি ঠিক আছে, সাইটের পৃষ্ঠাগুলির সমান? বিষয়টি তেমন নয়। বৈশিষ্ট্যটি কোনও পৃষ্ঠার মধ্যে কিছু স্নিপেট (যেমন গুগল ম্যাপ সাইডবারে প্রদর্শিত হবে), বা কোনও ধরণের কার্যকারিতা (যেমন ব্যবহারকারীরা কিছু ডেটা রফতানি করতে পারেন) হতে পারে।
স্ট্যাকওভারফ্লো নিউবিবি

আপনি সঠিক, তবে আপনার অর্থ কি এমন কিছু ব্লক যা বিভিন্ন পৃষ্ঠায় প্রদর্শিত হয়? আপনি এটি প্রদর্শন করতে বাধা কি? নির্দিষ্ট পৃষ্ঠা অনুসারে বা আপনি এটি প্রদর্শিত সমস্ত পৃষ্ঠায়
আকরাম ওয়াহিদ

বৈশিষ্ট্যগুলি একটি সম্পূর্ণ পৃষ্ঠা বা কোনও পৃষ্ঠার কেবল একটি অংশ বা কিছু কার্যকারিতা হতে পারে।
স্ট্যাকওভারফ্লো নিউবিবি 6:51

0

এই বৈশিষ্ট্যগুলি কেবল এইচটিটিপি অনুরোধের জন্য প্রয়োজন তা ধরে নিই।

আমি Featuresসমস্ত ডিফল্ট পতাকা সহ একটি ডিফল্ট বেস শ্রেণি তৈরি করব :

Class Features {
    // Defaults
    protected $feature1_enabled = true;
    protected $feature2_enabled = true;

    public function isFeature1Enabled(): bool
    {
        return $this->feature1_enabled;
    }

    public function isFeature2Enabled(): bool
    {
        return $this->feature2_enabled;
    }
}

তারপরে আমি প্রতিটি ডোমেনের জন্য সেই শ্রেণিটি প্রসারিত করব এবং সেই ডোমেনটির জন্য প্রয়োজনীয় ওভাররাইডগুলি সেট করব:

Class Domain1 extends Features {
    // override
    protected $feature1_enabled = false;
}

তারপরে কনটেইনারটিতে বৈশিষ্ট্যগুলির ক্লাস বাঁধতে একটি মিডওয়্যার তৈরি করুন:

class AssignFeatureByDomain
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        switch ($_SERVER['HTTP_HOST']) {
            case 'domain1':
                app()->bind(Features::class, Domain1::class);
                break;
            default:
                abort(401, 'Domain rejected');
        }

        return $next($request);
    }
}

এই মিডলওয়্যারটিকে আপনার রুটের সাথে সংযুক্ত করতে ভুলবেন না: একটি গ্রুপে বা প্রতিটি রুটের জন্য।

এর পরে আপনি আপনার নিয়ন্ত্রণকারীগুলিতে আপনার বৈশিষ্ট্যগুলির ক্লাসটি টাইপ হিন্ট করতে পারেন:

public function index(Request $request, Features $features)
{
    if ($features->isFeature1Enabled()) {
        //
    }
}

0

লারাভেল এটির সাথে দুর্দান্ত, আপনি এমনকি ডিবিতে আপনার বৈশিষ্ট্যগুলি সংরক্ষণ করতে পারেন এবং ডোমেনের মধ্যে একটি সম্পর্ক তৈরি করতে পারেন।

আমি গেটস এবং নীতিগুলি ব্যবহার করার পরামর্শ দেব, যা আপনাকে আপনার নিয়ন্ত্রণকারী এবং ব্লেড টেম্পলেটগুলিতে আরও ভাল নিয়ন্ত্রণ প্রদান করবে। এর অর্থ আপনি আপনার ডিবি থেকে ফটকগুলি নিবন্ধন করুন বা তাদের হার্ড কোড করুন।

উদাহরণস্বরূপ যদি আপনার সিস্টেমে একটি বোতাম সহ রফতানি পণ্য বৈশিষ্ট্য থাকে এবং আপনি কিছু ব্যবহারকারীর কাছে সেই বৈশিষ্ট্যটি উপলভ্য করতে চান তবে আপনি ব্যবসার যুক্তি দিয়ে গেটগুলি নিবন্ধভুক্ত করতে পারেন।

//Only admins can export products
Gate::define('export-products', function ($user) {
    return $user->isAdmin;
});

তারপরে আপনি নিয়ামকগুলিতে নিম্নলিখিতগুলি করতে পারেন

<?php

namespace App\Http\Controllers;

use App\Product;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class ProductsController extends Controller
{
    /**
     * Export products
     *
     * @param  Request  $request
     * @param  Post  $post
     * @return Response
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function export(Request $request)
    {
        $this->authorize('export-products');

        // The current user can export products
    }
}

আপনার ব্লেড টেম্পলেটগুলির জন্য এখানে একটি উদাহরণ রয়েছে:

@can('export-products', $post)
    <!-- The Current User Can export products -->
@endcan

@cannot('export-products')
    <!-- The Current User Can't export products -->
@endcannot

https://laravel.com/docs/5.8/authorization এ আরও তথ্য উপলব্ধ


0

আকর্ষণীয় ঘটনা আপনার এখানে আছে। আপনার Featureইন্টারফেস বা অ্যাবস্ট্রাক্ট শ্রেণিতে সন্ধান করা আকর্ষণীয় হতে পারে যা আপনার সাধারণত কয়েকটি পদ্ধতি ব্যবহার করে।

interface Feature
{
    public function isEnabled(): bool;

    public function render(): string;

    // Not entirely sure if this would be a best practice but the idea is to be
    // able to call $feature->execute(...) on any feature.
    public function execute(...);

    ...
}

এমনকি আপনি মধ্যে এই devide পারে ExecutableFeatureএবং RenderableFeature

জীবনকে আরও সহজ করার জন্য আরও কিছু ধরণের কারখানার শ্রেণি তৈরি করা যেতে পারে।

// Call class factory.
Feature::make('some_feature')->render();
...->isEnabled();

// Make helper method.
feature('some_feature')->render();

// Make a blade directives.
@feature('some_feature')
@featureEnabled('some_feature')

0

আমি আমার ক্ষেত্রে যা করেছি তা ডাটাবেসে একটি নতুন টেবিল তৈরি করছিল, আপনি Domainsউদাহরণ হিসাবে এটি কল করতে পারেন ।

সমস্ত সুনির্দিষ্ট বৈশিষ্ট্য যুক্ত করুন, সেগুলি কিছু ডোমেনে প্রদর্শিত হতে পারে তবে বাকিগুলিতে নয়, সেই টেবিলের কলাম হিসাবে বুলিয়ান মানগুলির জন্য বিট। যেমন, আমার ক্ষেত্রে allow_multiple_bookings, use_company_card... যাই হোক না কেন।

তারপরে, একটি শ্রেণি Domainএবং তার সম্পর্কিত ভান্ডার তৈরি করার কথা বিবেচনা করুন এবং আপনার কোডটিতে এই মানগুলি জিজ্ঞাসা করুন, আপনার ডোমেনে (আপনার মডেল, অ্যাপ্লিকেশন পরিষেবাগুলি, ইত্যাদি) যতটা সম্ভব যুক্তিটি চাপানোর চেষ্টা করবেন।

উদাহরণস্বরূপ, আমি RequestBookingডোমেন যা বুকিংয়ের জন্য অনুরোধ করছে কেবলমাত্র এক বা একাধিক অনুরোধ করতে পারে তার জন্য আমি নিয়ামক পদ্ধতিটি পরীক্ষা করব না ।

পরিবর্তে আমি এটি RequestBookingValidatorServiceএমনটি করে যা যাচাই করতে পারে যে বুকিংয়ের ডেটটাইম কেটে গেছে কিনা, ব্যবহারকারীর একটি সক্ষম ক্রেডিট কার্ড, ... বা ডোমেন যা এই ক্রিয়াটি এসেছে তা একাধিক বুকিংয়ের জন্য অনুরোধ করার অনুমতি পেয়েছে (এবং তারপরে এটি ইতিমধ্যে থাকলে থাকে)।

এটি পাঠযোগ্যতার সুবিধার্থে যোগ করে, কারণ আপনি এই সিদ্ধান্তটিকে আপনার অ্যাপ্লিকেশন পরিষেবাগুলিতে ঠেলে দিয়েছেন pushed এছাড়াও, আমি এটি দেখতে পেয়েছি যে যখনই আমার কোনও নতুন বৈশিষ্ট্যের প্রয়োজন হবে তখন আমি টেবিলটিতে সেই বৈশিষ্ট্যটি যুক্ত করতে লারাভেল (বা সিমফনি) মাইগ্রেশন ব্যবহার করতে পারি এবং আমি যে কোডটি কোড করেছিলাম তার সাথে আমি যে মানগুলি চাই তার সাথে তার সারিগুলি (আপনার ডোমেনগুলি) আপডেটও করতে পারি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.