Каков наилучший шаблон проектирования для использования REST API? - PullRequest
1 голос
/ 16 июня 2019

Я хочу использовать Rest API в Laravel (инфраструктура MVC), но я прибегаю к использованию __call, и мне было интересно, есть ли лучший шаблон проектирования для этого.

Я знаю, что это плохой выбори я ищу альтернативный шаблон, но вот мой класс репозитория:

namespace App\Repositories;

use App\Models\OnlinePayment;
use App\Models\Order;
use App\Models\Transaction;
use App\Models\User;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use SoapClient;

class Bank
{
    protected $http;
    protected $user;

    public function __construct()
    {
        $this->http = new Client;
    }

    protected function index()
    {
        $url = config('Bank.url') . '/v2/quantum/users/' . $this->user->national_id . '/report';

        $data = [
            'user_gender'       => $this->user->gender ?? 1,
            'user_name'         => $this->user->name,
            'user_family'       => $this->user->family ?? 'خالی',
            'user_mobile'       => $this->user->mobile,
            'user_type'         => $this->user->type->name,
        ];

        $options = $this->options($data);
        $res = $this->http->request('GET', $url, $options);

        $response = json_decode($res->getBody(), true);

        return $response;
    }

    protected function indexData($request)
    {
        $url = config('Bank.url') . '/v2/quantum/users/' . $this->user->national_id . '/customers';

        $options = $this->options($request->all());
        $res = $this->http->request('GET', $url, $options);
        $response = response()->json(json_decode($res->getBody(), true), $res->getStatusCode());
        return $response;
    }

    protected function show($national_id)
    {
        $url = config('Bank.url') . '/v2/quantum/users/' . $this->user->national_id . '/customers/' . $national_id;

        $options = $this->options([]);
        $res = $this->http->request('GET', $url, $options);

        if ($res->getStatusCode() == 404) {
            abort(404);
        }
        $response = json_decode($res->getBody(), true);

        return $response;

    }

    protected function store($request)
    {
        $http = new Client;
        $url = config('Bank.url') . '/v2/quantum/users/' . $this->user->national_id . '/customers';
        $this->user = auth()->user();

        $data = array_merge(
            [
                'customer_national_id'  => $request->national_id,
                'customer_gender'       => $request->gender,
                'customer_name'         => $request->name,
                'customer_family'       => $request->family,
                'customer_phone'        => $request->phone,
                'customer_mobile'       => $request->mobile,
                'customer_city_id'      => $request->city_id,
            ], [
                'user_name'         => $this->user->nanfig() is a hidden dependency. The settings should also be passed via the construcme,
                'user_family'       => $this->user->family ?? 'خالی',
                'user_mobile'       => $this->user->mobile,
                'user_type'         => $this->user->type->name,
                'user_gender'       => $this->user->gender ?? 1,
            ]
        );

        $res = $http->request('POST', $url, [
            'headers' => [
                'Accept'        => 'application/json',
                'Content-Type'  => 'application/json',
                'Authorization' => 'Bearer ' . config('Bank.token'),
            ],
            'json' => $data,
            'http_errors' => false
        ]);

        if (! in_array($res->getStatusCode(), [200, 422])) {
            $error = ValidationException::withMessages([
                'name' => 'خطای ' . $res->getStatusCode() . ' در تعویض کالا'
            ]);
            throw $error;
        }

        $response = response()->json(json_decode($res->getBody(), true), $res->getStatusCode());
        return $response;
    }

    protected function options($data)
    {
        $options = [
            'headers' => [
                'Accept'        => 'application/json',
                'Content-Type'  => 'application/json',
                'Authorization' => 'Bearer ' . config('Bank.token'),
            ],
            'json' => $data,
            'http_errors' => false
        ];

        return $options;
    }

    public function __call($method, $arguments) {
        if (method_exists($this, $method)) {

            if (! isset($arguments[0]) || ! $arguments[0] instanceof User) {
                $this->user = auth()->user();
            } else {
                $this->user = $arguments[0];
                unset($arguments[0]);
            }

            return call_user_func_array(array($this, $method), $arguments);
        }
    }
}

, затем создайте его экземпляр в конструкторе контроллера:

    public function __construct()
    {

        $this->Bank = new Bank();
    }

и используйте его в контроллере какэто:

$response = $this->Bank->indexData($user, $request);

или это:

$response = $this->Bank->indexData($request);

Ответы [ 2 ]

0 голосов
/ 16 июня 2019

__ call - это магический метод php, который позволяет выполнять защищенный метод вне экземпляра объекта, это разрыв видимости класса.

Если вы хотите вызывать метод извне, он должен быть публичным

 public function __construct()
 {
    $this->bank = new Bank()
 }

Использовать автоинъекцию зависимости

public function __construct(Bank $bank)
{
   $this->bank = $bank;
}
0 голосов
/ 16 июня 2019

Я думаю, что показанный класс не является классом репозитория, потому что репозиторий отвечает только за чтение и запись даты из источника данных.Ваш класс делает слишком много и нарушает все основные принципы MVC.

Некоторые думают, что я бы исправил:

  • Репозиторий не отвечает за создание данных представления ответа (например, JSON)
  • Репозиторий не отвечает за создание объекта ответа
  • Репозиторий не зависит от запроса / ответа
  • Имя метода index не имеет смысла, поскольку репозиторий не являетсяКонтроллер действий.Не смешивайте слой модели со слоем контроллера.
  • config () - это скрытая зависимость.Настройки также должны передаваться через конструктор.

Вместо этого используйте лучшее разделение:

  • Создайте класс BankApiClient
  • Не используйте магические методы, такие как__call
  • Вместо этого используйте открытые методы, такие как: getUserByNationalId (int $ nationalId): UserData
  • и т. Д. ...
  • Позвольте действию контроллера создать / визуализировать jsonответ с результатами BankApiClient.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...