将索引操作拆分为多个操作是否是一种 RESTFUL 友好的方法



我需要向两个不同的用户组显示两个不同的索引页。例如,普通用户应该看到一个页面,而特权用户应该看到另一个页面。我看到两种解决此问题的方法:

一个带有条件的索引操作:

public function index()
{
    // view for privileged users
    if(request()->user()->hasRole('privileged')){
        return view('index_privileged');
    }
    // view for regular users
    if(request()->user()->hasRole('regular')){
        return view('index_regular');
    }
    return redirect('/');
}

多个操作:

public function index_privileged()
{
    return view('index_privileged');
}
public function index_regular()
{
    return view('index_regular');
}

哪种方法更"休息友好",通常更好?

我是灯光控制器的忠实粉丝。 对于一个简单的问题来说,这可能有点过分,但如果这样的事情再次出现,你已经完成了所有设置。

话虽如此,最好创建一个PrivilegedUser类和一个RegularUser类,并为它们提供一个返回各自视图的索引方法。 将它们编码到接口UserInterface,并确保它们都实现了这一点。

这是我测试中的样子。

class RegularUser implements UserInterface
{
    public function index()
    {
        return view('index_regular');
    }
}
class PrivilegedUser implements UserInterface
{
    public function index()
    {
        return view('index_privileged');
    }
}
interface UserInterface
{
    public function index();
}

然后,您可以添加一个侦听器,该侦听器应为事件IlluminateAuthEventsLogin运行。 当有人登录时,Laravel会自动为您触发此事件。 这将进入文件EventServiceProvider.php .

protected $listen = [
    'IlluminateAuthEventsLogin' => [
        'AppListenersAuthLoginListener',
    ],
];

现在,您可以运行php artisan event:generate来生成新的侦听器。 这是我的听众的样子,它应该适合你。

namespace AppListeners;
use IlluminateAuthEventsLogin;
use IlluminateFoundationApplication;
class AuthLoginListener
{
    /**
     * Create the event listener.
     *
     * @param Application $app
     */
    public function __construct(Application $app)
    {
        $this->app = $app;
    }
    /**
     * Handle the event.
     *
     * @param  Login  $event
     * @return void
     */
    public function handle(Login $event)
    {
        if ($event->user->hasRole('privileged')) {
            $this->app->bind('AppRepositoriesUserInterface', 'AppRepositoriesPrivilegedUser');
        } else if ($event->user->hasRole('regular')) {
            $this->app->bind('AppRepositoriesUserInterface', 'AppRepositoriesRegularUser');
        }
    }
}

从本质上讲,这是在告诉Laravel根据刚刚登录的用户类型加载某个类。 User实例可通过 Laravel 自动传入的 Login 对象获得。

现在一切都设置好了,我们几乎不需要在控制器中做任何事情,如果您需要执行更多因用户而异的操作,只需将它们添加到 RegularUser 或 PrivilegedUser 类即可。 如果你有更多的用户类型,只需为他们编写一个实现接口的新类,在你的AuthLoginListener中添加一个额外的 else ,你应该很高兴。

要使用它,在您的控制器中,您需要执行以下操作...

// Have Laravel make our user class
$userRepository = App::make('AppRepositoriesUserInterface');
return $userRepository->index()->with('someData', $data);

或者更好的是,将其作为依赖项注入。

use AppRepositoriesUserInterface;
class YourController extends Controller
{
    public function index(UserInterface $user)
    {
        return $user->index();
    }
}

编辑:

我刚刚意识到,如果没有满足条件,我忘记了您要return redirect('/');的部分。 你可以创建一个新的类GuestUser(我知道这听起来像是矛盾的),它实现了UserInterface但不是使用AuthLoginListener,而是在Laravel启动时将其绑定到服务提供商中。 这样,Laravel在需要实现UserInterface时将始终有返回的内容,以防在没有人登录的情况下需要这个类。

嗯,它更像是一个重构"问题",而不是一个休息友好的问题。查看本指南,您可以看到使 API 友好的大多数事情都与 url 有关。
但是,让我们回答您的问题。您要做的是重构方法,但它不仅是移动方法,而且类似于提取变量。

第二个

选项将使代码更具可读性,无论哪种方式都是正确的,但第二个选项对开发人员更友好。它增强了任何开发人员的代码可读性。我建议使用第二个选项。

重构永远不够,但是阅读这样的东西,它会帮助你编写更多可读的代码。

最新更新