Мы начнем с проверки нашей формы. Это только часть проблемы, поскольку пользователь с токеном может легко отправить запрос POST с недопустимыми данными, и он будет принят. Это, по крайней мере, остановит целую кучу недействительных запросов данных и улучшит UX при добавлении нового кафе.

Во-первых, я обычно добавляю объект проверки к данным, возвращаемым из компонента. Я делаю по одному для каждой части данных, которую мы проверяем. Ваши данные должны выглядеть так:

data(){
  return {
    name: '',
    address: '',
    city: '',
    state: '',
    zip: '',
    validations: {
      name: {
        is_valid: true,
        text: ''
      },
      address: {
        is_valid: true,
        text: ''
      },
      city: {
        is_valid: true,
        text: ''
      },
      state: {
        is_valid: true,
        text: ''
      },
      zip: {
        is_valid: true,
        text: ''
      }
    }
  }
},

Теперь у нас есть заполнители для проверки для каждой части данных, которые мы собираем. В каждом фрагменте данных у нас есть поле is_valid, для которого по умолчанию установлено значение true, и пустое текстовое поле, которое мы можем заполнить текстом проверки.

Шаг 2. Добавьте уведомления о проверке

Далее нам нужно добавить уведомления пользователю о недопустимых данных. Я делаю это с <span> элементами, которые отображаются, если данные недействительны. Например, проверка поля имени должна выглядеть так:

<span class="validation" v-show="!validations.name.is_valid">{{ validations.name.text }}</span>

Это показывает проверку, если она помечена как недействительная. Он также отображает текст для недопустимого поля имени. Таким образом мы можем пометить поле как недопустимое и при необходимости отобразить настраиваемый текст. Иногда поле может быть недопустимым по многим причинам, поэтому наличие переменной для текста очень помогает.

Я также добавил в каталог /resources/assets/sass/components простой компонент под названием _validations.scss. Он просто стилизует интервал проверки как блок и текст красным цветом. Я также включил его в /resources/assets/sass/app.scss, так что проверьте его на https://github.com/serversideup/roastandbrew.

Шаг 3. Создайте функцию проверки JS

Так мы проверяем новое кафе. Я делаю функцию проверки довольно простой. Честно говоря, существует миллион различных способов реализации ваших проверок, поэтому выберите то, что вам удобнее всего. Я обычно так подхожу к этому.

Сначала определите, как выглядят действительные данные для каждого объекта:
1. name: необходимо ввести строку
2. address: ввести строку.
3. city: необходимо ввести строку должен быть введен.
4. state: необходимо ввести строку.
5. zip: необходимо ввести строку, которая должна иметь правильный формат почтового индекса.

Наши данные сейчас не слишком сложные, но по мере добавления функций они будут становиться все более сложными.

Затем просто добавьте метод к объекту методов в компоненте NewCafe.vue:

validateNewCafe(){

}

Затем инициализируйте переменную, которая определяет, действительна ли новая форма кафе, и установите для нее значение true. Таким образом, если мы обнаруживаем недействительные данные, мы помечаем их как ложные и не отправляем запрос. Затем мы возвращаем переменную.

validateNewCafe(){
  let validNewCafeForm = true;

  return validNewCafeForm;
}

Теперь мы оборачиваем нашу функциональность в метод submitNewCafe() с нашим методом проверки. Таким образом, функция вызывается только в том случае, если форма действительна:

submitNewCafe(){
  if( this.validateNewCafe() ){
    this.$store.dispatch( 'addCafe', {
      name: this.name,
      address: this.address,
      city: this.city,
      state: this.state,
      zip: this.zip
    });
  }
},

Теперь мы реализуем наши валидационные проверки. Наш validateNewCafe() метод должен выглядеть так:

validateNewCafe(){
        let validNewCafeForm = true;

        /*
          Ensure a name has been entered
        */
        if( this.name.trim() == '' ){
          validNewCafeForm = false;
          this.validations.name.is_valid = false;
          this.validations.name.text = 'Please enter a name for the new cafe!';
        }else{
          this.validations.name.is_valid = true;
          this.validations.name.text = '';
        }

        /*
          Ensure an address has been entered
        */
        if( this.name.trim() == '' ){
          validNewCafeForm = false;
          this.validations.address.is_valid = false;
          this.validations.address.text = 'Please enter an address for the new cafe!';
        }else{
          this.validations.address.is_valid = true;
          this.validations.address.text = '';
        }

        /*
          Ensure a city has been entered
        */
        if( this.city.trim() == '' ){
          validNewCafeForm = false;
          this.validations.city.is_valid = false;
          this.validations.city.text = 'Please enter a city for the new cafe!';
        }else{
          this.validations.city.is_valid = true;
          this.validations.city.text = '';
        }

        /*
          Ensure a state has been entered
        */
        if( this.state.trim() == '' ){
          validNewCafeForm = false;
          this.validations.state.is_valid = false;
          this.validations.state.text = 'Please enter a state for the new cafe!';
        }else{
          this.validations.state.is_valid = true;
          this.validations.state.text = '';
        }

        /*
          Ensure a zip has been entered
        */
        if( this.zip.trim() == '' || !this.zip.match(/(^\d{5}$)/) ){
          validNewCafeForm = false;
          this.validations.zip.is_valid = false;
          this.validations.zip.text = 'Please enter a valid zip code for the new cafe!';
        }else{
          this.validations.zip.is_valid = true;
          this.validations.zip.text = '';
        }

        return validNewCafeForm;
      }

Он просто проверяет, что что-то введено в каждое поле, и с помощью почтового индекса проверяет, соответствует ли он действительному почтовому индексу. Если поле недействительно, мы устанавливаем для is_valid для этого поля значение false, которое будет отображать проверку. Мы также установим поле text как отображение для проверки. Наконец, мы устанавливаем форму как недействительную, чтобы она не отправлялась. Если вы попытаетесь ввести пустое поле для любого из полей формы, оно должно выглядеть так:

Мы сейчас проверяем нашу форму на ошибку! Теперь мы должны провести серьезную проверку на стороне API, чтобы мы могли подтвердить, что данные действительны, прежде чем мы их сохраним.

Шаг 4: Создайте валидатор запросов Laravel для нового кафе

Пришло время выполнить проверку на стороне сервера. Это гарантирует, что любой запрос к нашей конечной точке, независимо от того, поступает он через форму или нет, будет проверен перед добавлением данных. В Laravel есть несколько приятных инструментов, которые упрощают эту задачу: Проверка - Laravel - PHP Framework для веб-мастеров.

Сначала сделаем новый запрос согласно документации. Итак, что мы сделаем, это запустим:

php artisan make:request StoreCafeRequest

Это создаст запрос с именем StoreCafeRequest в нашем каталоге /app/Http/Requests. Мы проверим наш новый запрос в кафе с помощью этого валидатора.

Затем откройте /app/Http/Requests/StoreCafeRequest.php. По умолчанию там вы найдете 2 метода. Во-первых, это метод authorize(). Этот метод предоставляет запрашивающей стороне разрешение на выполнение запроса. Поскольку мы проверены нашим токеном, а запрос находится за промежуточным программным обеспечением auth:api, мы устанавливаем эту функцию так, чтобы она возвращала true. Пока пользователь вошел в систему, он может добавить новое кафе.

Другой метод, который вы видите, - это метод rules(). Здесь мы определяем проверки для входящих данных. Это массив, в котором есть ключ, который соответствует имени ключа запроса POST, поступающего в приложение, и значение, которое представляет собой строку, которая может быть любым из правил проверки, определенных здесь: Проверка - Laravel - PHP Framework для веб-мастеров »

Правила валидации сразу могут сбить с толку, но, надеюсь, приведенные нами примеры помогут им прояснить ситуацию.

Нам нужно настроить наши правила, чтобы быть готовыми к сопоставлению входящих данных следующим образом:

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'name'    => '',
        'address' => '',
        'city'    => '',
        'state'   => '',
        'zip'     => ''
    ];
}

Прямо сейчас у нас есть только ключ, который соответствует входящим данным, и пустая строка, которую мы будем заполнять для проверки.

Все поля должны иметь проверку required. Итак, в массиве добавьте required для каждого поля:

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'name'    => 'required',
        'address' => 'required',
        'city'    => 'required',
        'state'   => 'required',
        'zip'     => 'required'
    ];
}

Для разделения каждого типа проверки вы можете использовать символ |. Таким образом, вы можете иметь несколько типов проверок для каждого поля. Единственное поле, где нам нужно более одной проверки, - это поле zip, где должно быть 5 чисел. Мы настроили эту проверку с помощью регулярного выражения, аналогичного тому, что мы сделали на стороне javascript: 'required|regex:/\b\d{5}\b/'

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

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'name'    => 'required',
        'address' => 'required',
        'city'    => 'required',
        'state'   => 'required',
        'zip'     => 'required|regex:/\b\d{5}\b/'
    ];
}

Теперь у нас есть проверки на стороне сервера, аналогичные нашим проверкам Javascript! Если какой-либо из этих запросов завершится ошибкой, мы получим ответ (400 Bad Request) от сервера, и неверные данные не будут введены в нашу систему! Мы также можем отловить эти ошибки и отобразить их пользователю.

По мере роста этого приложения будет больше сценариев, в которых мы будем выполнять более сложные проверки. Я объясню их так же хорошо, как мы!

Шаг 5. Определите сообщения об ошибках проверки

Теперь, когда мы написали наши проверки, мне нравится определять собственные сообщения об ошибках для каждого из недопустимых полей. Для этого добавьте метод messages() после метода rules(). и добавьте пустой массив, который будет возвращен следующим образом:

/**
 * Get the error messages for the defined validation rules.
 *
 * @return array
 */
public function messages()
{
    return [

    ];
}

Теперь для каждой проверки каждой переменной мы можем определить настраиваемое сообщение, которое возвращает правильный ответ. Формат, используемый для определения этих сообщений, следующий:
{key}.{validation} => {message}

Таким образом, ключом будет имя переменной, проверка будет типом проверки, например required, а сообщение будет настраиваемым сообщением, которое мы хотим вернуть.

Наш массив сообщений должен выглядеть так:

/**
 * Get the error messages for the defined validation rules.
 *
 * @return array
 */
public function messages()
{
    return [
      'name.required'     => 'A name for the cafe is required.',
      'address.required'  => 'An address is required to add this cafe.',
      'city.required'     => 'A city is required to add this cafe.',
      'state.required'    => 'A state is required to add this cafe.',
      'zip.required'      => 'A zip code is required to add this cafe.',
      'zip.regex'         => 'The zip code entered is invalid.'
    ];
}

Обратите внимание, как в поле zip есть 2 сообщения для разных проверок? Таким образом, если я ввожу что-то для почтового индекса, но он недействителен, мы сможем вернуть точное сообщение, которое нам нужно, чтобы помочь пользователю указать, что ему следует ввести.

Наш запрос на валидацию должен выглядеть так:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreCafeRequest 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 [
            'name'    => 'required',
            'address' => 'required',
            'city'    => 'required',
            'state'   => 'required',
            'zip'     => 'required|regex:/\b\d{5}\b/'
        ];
    }

    /**
     * Get the error messages for the defined validation rules.
     *
     * @return array
     */
    public function messages()
    {
        return [
          'name.required'     => 'A name for the cafe is required.',
          'address.required'  => 'An address is required to add this cafe.',
          'city.required'     => 'A city is required to add this cafe.',
          'state.required'    => 'A state is required to add this cafe.',
          'zip.required'      => 'A zip code is required to add this cafe.',
          'zip.regex'         => 'The zip code entered is invalid.'
        ];
    }
}

One thing to remember, we can create a validator for any type of form whether it’s a PUT, DELETE, or POST request.

There are ways to create custom validation rules as well if the defined set of rules doesn’t match a use case you may have. We will be going through a tutorial on this later as well.

Step 6: Add Request To Controller Route

Since we have our validation created, we need to add the request to the controller route.

First, we need to open up App\Http\Controllers\API\CafesController.php and declare the the request we are using to the top of the controller like this:

/*
    Defines the requests used by the controller.
*/
use App\Http\Requests\StoreCafeRequest;

Это сообщает нашему контроллеру, что мы используем только что созданный StoreCafeRequest.php.

Теперь нам нужно вставить запрос в наш postNewCafe() метод, поэтому мы делаем это следующим образом:

public function postNewCafe( StoreCafeRequest $request ){
    $cafe = new Cafe();

    $cafe->name     = Request::get('name');
    $cafe->address  = Request::get('address');
    $cafe->city     = Request::get('city');
    $cafe->state    = Request::get('state');
    $cafe->zip      = Request::get('zip');

    $cafe->save();

    return response()->json($cafe, 201);
  }

Теперь, перед запуском нашего метода, валидатор проверяет правильность введенных данных. Наконец, мы обновляем назначение, чтобы не использовать фасад Request, и использовать объект $request для хранения запроса кафе следующим образом:

/*
|-------------------------------------------------------------------------------
| Adds a New Cafe
|-------------------------------------------------------------------------------
| URL:            /api/v1/cafes
| Method:         POST
| Description:    Adds a new cafe to the application
*/
public function postNewCafe( StoreCafeRequest $request ){
  $cafe = new Cafe();

  $cafe->name     = $request->get('name');
  $cafe->address  = $request->get('address');
  $cafe->city     = $request->get('city');
  $cafe->state    = $request->get('state');
  $cafe->zip      = $request->get('zip');

  $cafe->save();

  return response()->json($cafe, 201);
}

Теперь у нас завершена проверка на стороне сервера!

Вывод

Это очень простой пример того, как выполнить как проверку javascript в VueJS, так и проверку Laravel в PHP. По мере роста приложения эти проверки будут становиться все более сложными. Однако хорошо иметь их, чтобы в вашем приложении не оставались неверные данные. Конечно, вы можете увидеть весь код на GitHub - serverideup / roastandbrew

Привет! Мы пишем книгу о разработке приложений на основе API. Узнай первым, когда он будет готов! Зарегистрируйтесь здесь: Регистрация разработки приложений на основе API