Поддерживает ли Laravel «типизированные» запросы? - PullRequest
1 голос
/ 28 июня 2019

Для преобразования объекта базы данных в ответ API, ресурсы поддержки Laravel, например. UserResource extends JsonResource. Ресурс позволяет мне четко определить, какие поля из сущности следует включить в ответ, как их преобразовать и т. Д.

Есть ли подобный функционал для запросов? Мои запросы обычно выглядят так:

public function create(JsonRequest $request): UserResource
{
    $data = $request->json()->all();
    /* Remove, transform, add request fields etc. */
    $user = User::create($data);
    $user->save();
    return new UserResource($user);
}

В нашем случае у нас есть устаревшая база данных за современным API, поэтому существует ряд полей, которые необходимо преобразовать, переименовать и т. Д., Прежде чем помещать их в класс сущностей. Поля отличаются от запроса к запросу, но шаги очень похожи. Есть ли менее наглядный способ сделать это, что-то похожее на то, как ресурсы преобразуют сущности в ответы?

Что-то вроде:

class UserRequest extends JsonRequest {
  public function fromArray(JsonRequest $request) {
    …
  }
}

Тогда запрос может выглядеть так:

public function create(UserRequest $request): UserResource
{
    $user = User::create($request);
    $user->save();
    return new UserResource($user);
}

1 Ответ

1 голос
/ 28 июня 2019

Я полагаю, что большинство ваших проблем может решить запрос формы . Смотрите пример ниже

Форма запроса класса:

namespace App\Http\Requests;

use Carbon\Carbon;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;

class TestRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'date' => 'required|date_format:Y-m-d H:i:s',
            'name' => 'required|string',
        ];
    }

    // here you can specify custom error messages
    public function messages()
    {
        return [
            'date.required' => 'No date specified',
            'date.date_format' => 'Invalid date format',
            'name.required' => 'No name specified',
            'name.string' => 'Invalid name format',
        ];
    }

    // here you can implement some data mapping before validation
    protected function validationData()
    {
        return $this->transform($this->all());
    }

    // some data transformation logic
    // You can place it anywhere in your applciation services
    protected function transform($input)
    {
        $transformed = [];
        foreach ($input as $field => $value) {
            if ($field == 'name') {
                $value = strtoupper($value);
            } elseif ($field == 'date') {
                $value = Carbon::parse($value)->toDateTimeString();
            }
            $transformed[$field] = $value;
        }
        return $transformed;
    }

    public function failedValidation(Validator $validator)
    {
        // here you can implement custom validation failure
        parent::failedValidation($validator);
    }
}

Вот мой тестовый маршрут: Route::get('/test', 'TestController@index');

И контроллер:

use App\Http\Requests\TestRequest;

class TestController extends Controller
{

    public function index(TestRequest $request)
    {
        return response()->json($request->validated());
    }
}

Итак, запрашивая маршрут: curl -H 'Accept: application/json' 'http://localhost:8000/test?date=01.01.2019&name=petya'

и получение ответа: {"date":"2019-01-01 00:00:00","name":"PETYA"}

И не стесняйтесь видеть исходный код запроса и формы запроса, потому что не все методы, которые вы хотите, описаны в документации. Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...