• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

使用Laravel RESTful后端构建React应用程序:第1部分(Laravel 5.5 API)

Laravelreact 是用于构建现代 Web 应用程序的两种流行的 Web 开发技术。Laravel 是一个突出的服务器端 php框架,而 React 是一个客户端javascript库。本教程作为 Laravel 和 React 的介绍,将它们结合起来创建一个现代 Web 应用程序。 

在现代 Web 应用程序中,服务器通过一些 api(应用程序编程接口)端点管理后端的工作有限。客户端向这些端点发送请求,服务器返回响应。但是,服务器并不关心客户端如何渲染视图,这完全符合关注点分离原则。这种架构允许开发人员为 Web 和不同设备构建健壮的应用程序。 

在本教程中,我们将使用最新版本的 Laravel 5.5 版来创建 restful 后端 API。前端将包含用 React 编写的组件。我们将构建一个资源丰富的产品列表应用程序。本教程的第一部分将更多地关注 Laravel 概念和后端。让我们开始吧。 

介绍

Laravel 是一个为现代 Web 开发的 PHP 框架。它有一种表达性的语法,有利于约定而不是配置范式。Laravel 具有开箱即用的项目启动所需的所有功能。但就个人而言,我喜欢 Laravel,因为它将 PHP 开发变成了完全不同的体验和工作流程。  

另一方面,React 是 Facebook 开发的一个流行的 JavaScript 库,用于构建单页应用程序。React 帮助您将视图分解为组件,其中每个组件描述应用程序 UI 的一部分。基于组件的方法具有组件可重用性和模块化的额外好处。

为什么选择 Laravel 和 React?

如果您正在为 Web 开发,您可能倾向于为服务器和客户端使用单个代码库。然而,并不是每家公司都给予开发者使用他们选择的技术的自由并且有一些很好的理由。为整个项目使用 javaScript 堆栈是当前的常态,但没有什么能阻止您为服务器端和客户端选择两种不同的技术。 

那么 Laravel 和 React 结合得如何呢?很好,事实上。尽管 Laravel 已经记录了对vue .js 的支持,这是另一个 JavaScript 框架,但我们将在前端使用 React,因为它更受欢迎。

先决条件

在开始之前,我将假设您对 RESTful 架构以及 API 端点的工作方式有基本的了解。此外,如果你之前有 React 或 Laravel 的经验,你将能够充分利用本教程。 

但是,如果您对这两个框架都不熟悉,请不要担心。本教程是从初学者的角度编写的,您应该能够轻松赶上。您可以在GitHub 上找到本教程的源代码。

安装和设置你的 Laravel 项目

Laravel 使用Composer来管理所有的依赖。因此,在开始使用 Laravel 之前,请在您的机器上下载并安装Composer您可能还需要配置路径环境变量,以便全局访问 Composer。

运行以下命令下载 laravel 安装程序。

composer global require "laravel/installer"

如果您已正确配置$PATH变量并添加~/.composer/vendor/bin到路径中,您应该能够生成一个新的 Laravel 项目,如下所示:

laravel new PROJECT-NAME

或者,您可以使用 Composer 创建一个没有 laravel 安装程序的新项目。

composer create-project --prefer-dist laravel/laravel blog

如果一切顺利,您应该能够在http://localhost:8000.

php artisan serve

注意:Artisan 是一个命令行工具,在使用 Laravel 时你离不开它。Artisan 接受大量命令,可让您为应用程序生成代码。运行 php artisan list查看所有可用的工匠命令。

配置环境

您的应用程序将在根目录中有一个.env文件。所有特定于环境的配置信息都在这里声明。如果您还没有为您的应用程序创建一个数据库,则将数据库详细信息添加到.env文件中。

DB_CONNECTION= mysql
DB_HOST=127.0.0.1DB_PORT=3306
DB_dataBASE=sampledb
DB_USERNAME=rootDB_PASSWORD=

了解模型、路由和控制器

Laravel 是一个遵循模型-视图-控制器(MVC)架构的框架。从广义上讲,MVC 帮助您将数据库查询(模型)与与如何处理请求(控制器)和如何呈现布局(视图)相关的逻辑分开。下图展示了典型 Laravel 应用程序的工作原理。 

使用Laravel RESTful后端构建React应用程序:第1部分(Laravel 5.5 API)  第1张Laravel 的架构。控制器返回响应,因此不需要视图层。

由于我们正在使用 Laravel 构建 API,因此我们将讨论仅限于模型和控制器。我们将在本教程的第二部分回顾我们创建视图的选项。 

路由器

当服务器收到一个 HTTP 请求时,Laravel 会尝试将它与在任何路由文件中注册的路由匹配。所有路由文件都位于 routes 目录中。routes/web.php托管 Web 界面的路由,而routes/api.php托管 API 的路由。在api.php中注册的路由将带有前缀/api(如在 localhost:3000/api 中)。如果您需要更改此行为,您应该前往 /app/Providers/RouteServiceProvider.phpRouteServiceProvider中的类 并在那里进行更改。 

由于我们正在构建产品列表应用程序,因此这里是 API 的端点以及与这些端点关联的 HTTP 操作。 

  • GET /products/:检索所有产品。

  • GET /product/{id}:检索与id.

  • post /products:创建一个新产品并将其插入数据库。

  • PUT /products/{id} :更新与id.

  • DELETE /products/{id}:删除给定的产品id

让我们正确使用术语。GET、POST、PUT 和 DELETE 是构建 RESTful 服务所必需的 HTTP 动词(通常称为 HTTP 方法)。/products是与产品资源关联的 URI。HTTP 方法请求服务器对给定资源执行所需的操作。

使用Laravel RESTful后端构建React应用程序:第1部分(Laravel 5.5 API)  第2张GET、POST、PUT 和 DELETE 是常用的 REST 动作

路由器允许您声明资源的路由以及针对该资源的 HTTP 方法。这是一个返回一些硬编码数据的示例路由文件。

路线/api.php

/**
** Basic Routes for a RESTful service:
**
** Route::get($uri, $callback);
** Route::post($uri, $callback);
** Route::put($uri, $callback);
** Route::delete($uri, $callback);
**
**/

Route::get('products', function () {
    return response(['Product 1', 'Product 2', 'Product 3'],200);
});

Route::get('products/{product}', function ($productId) {
    return response()->json(['productId' => "{$productId}"], 200);
});
 

Route::post('products', function() {
    return  response()->json([
            'message' => 'Create success'
        ], 201);
});

Route::put('products/{product}', function() {
	return  response()->json([
            'message' => 'Update success'
        ], 200);
});

Route::delete('products/{product}',function() {
	return  response()->json(null, 204);
});

如果要验证路由是否按预期工作,则应使用 POSTMAN 或curl之类的工具。

产品型号

products 资源需要一个可以与数据库交互的模型。模型是位于数据库之上的层,隐藏了所有特定于数据库的行话。Laravel 使用 Eloquent ORM 对数据库进行建模。 

Laravel 中包含的 Eloquent ORM 提供了一个漂亮、简单的 ActiveRecord 实现来处理你的数据库。每个数据库表都有一个相应的“模型”,用于与该表进行交互。模型允许您查询表中的数据,以及将新记录插入表中。 
— Laravel 文档

那么数据库模式定义呢?Laravel 的迁移解决了这个问题。Artisan 有一个迁移命令,可让您定义架构并在以后逐步更新它。让我们为 Product 实体创建一个模型和一个迁移。 

$ php artisan make:model Product -m

注意:那里有很多 Artisan 命令,很容易迷路。因此,每个工匠命令都包含一个帮助屏幕,该屏幕显示其他信息,例如可用的选项和参数。要进入帮助页面,命令的名称应该以help运行以下帮助命令以查看该-m选项代表什么: $ php artisan help make:model .

这是生成的迁移文件。

数据库/迁移/timestamp_create_products_table.php

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProductsTable extends Migration
{
  
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

  
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

up在将新表和列迁移到数据库时调用该方法,而在回滚down迁移时调用该方法。我们为具有三行的表创建了一个模式:  idcreated_atupdated_at$table->timestamps()方法负责维护created_atupdated_at列。让我们在模式定义中再添加几行。

   /* Let's add columns for title, description, price, availability */
   
   public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
            $table->string('title');
            $table->text('description');
            $table->integer('price');
            $table->boolean('availability');
        });
    }

我们用四个新列更新了架构。Laravel 的模式构建器支持多种列类型,如stringtextinteger,boolean等。

要执行挂起的迁移,您必须运行以下命令:

php artisan migrate

按照惯例,Laravel 假设Product模型与products表相关联。但是,如果您需要将模型与自定义表名相关联,则可以使用该$table属性来声明表名。然后该模型将与名为 custom_products的表相关联。

protected $table = 'custom_products';

但我们会保持简单并遵守约定。生成的 Product 模型位于app/目录中。尽管模型类可能看起来是空的,但它配备了各种查询构建器方法,您可以使用这些方法来查询数据库。例如,您可以使用Product::all()检索所有产品或Product::find(1)检索 id 为 1 的特定产品。 

Laravel 模型具有针对批量分配漏洞的内置保护机制该 fillable属性用于声明可以安全地批量分配的属性名称。 

应用程序/产品.php

/* Add the fillable property into the Product Model */

protected $fillable = ['title', 'description', 'price', 'availability'];

上面的代码将 和属性列入白名单title并将它们视为可批量分配的。我们现在可以使用该方法将新行插入到 products 表中。 descriptionpriceavailabilityProduct::create

数据库播种

Laravel 允许您使用虚拟数据填充您的开发和生产数据库,然后您可以使用这些数据来测试您的 API 端点。您可以通过执行以下 Artisan 命令来创建种子类。

$ php artisan make:seeder ProductsTableSeeder

生成的种子文件将放置在 database/seeds目录中。

要生成虚拟数据,您可以使用类似 str_random(10)返回随机字符串的方法。但是如果您需要与实际数据足够接近的数据,您应该使用类似 faker 库的东西。Faker 是一个第三方库,随 Laravel 框架一起提供,用于生成假数据。

数据库/种子/ProductsTableSeeder.php

use App\Product;

class ProductsTableSeeder extends Seeder
{
    public function run()
    {

        $faker = \Faker\Factory::create();

        // Create 50 product records
        for ($i = 0; $i < 50; $i++) {
            Product::create([
                'title' => $faker->title,
                'description' => $faker->paragraph,
                'price' => $faker->randomNumber(2),
                'availability' => $faker->boolean(50)
            ]);
        }
    }
}

执行db:seedartisan 命令来填充数据库。 

$ php artisan db:seed --class=ProductsTableSeeder

让我们回到routes/api.php并填写缺失的部分。

路线/api.php

/**
**Basic Routes for a RESTful service:
**Route::get($uri, $callback);
**Route::post($uri, $callback);
**Route::put($uri, $callback);
**Route::delete($uri, $callback);
**
*/
Route::get('products', function () {
    return response(Product::all(),200);
});

Route::get('products/{product}', function ($productId) {
    return response(Product::find($productId), 200);
});
 

Route::post('products', function(Request $request) {
   $resp = Product::create($request->all());
    return $resp;

});

Route::put('products/{product}', function(Request $request, $productId) {
    $product = Product::findOrFail($productId);
    $product->update($request->all());
    return $product;
});

Route::delete('products/{product}',function($productId) {
	Product::find($productId)->delete();

    return 204;

});

控制器

路由文件当前承载路由和处理请求的逻辑。我们可以将请求处理逻辑移到 Controller 类中,以便我们的代码更好地组织和更具可读性。我们先生成一个控制器类。

$ php artisan make:controller ProductsController

Controller 类包含对应于不同 HTTP 操作的各种方法(索引、显示、存储、更新和删除)。我已将请求处理逻辑从路由移至控制器。

app/HTTP/Controllers/ProductsController.php

<?php

namespace App\Http\Controllers;

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

class ProductsController extends Controller
{

    public function index()
	{
	    return Product::all();
	}

	public function show(Product $product)
	{
	    return $product;
	}

	public function store(Request $request)
	{
	    $product = Product::create($request->all());

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

	public function update(Request $request, Product $product)
	{
	    $product->update($request->all());

	    return response()->json($product, 200);
	}

	public function delete(Product $product)
	{
	    $product->delete();

	    return response()->json(null, 204);
	}

}

路线/api.php

/**
**Basic Routes for a RESTful service:
**Route::get($uri, $callback);
**Route::post($uri, $callback);
**Route::put($uri, $callback);
**Route::delete($uri, $callback);
**
*/


Route::get('products', 'ProductsController@index');

Route::get('products/{product}', 'ProductsController@show');

Route::post('products','ProductsController@store');

Route::put('products/{product}','ProductsController@update');

Route::delete('products/{product}', 'ProductsController@delete');

如果您没有注意到,我已经将 Product 实例注入到控制器方法中。这是 Laravel 隐式绑定的一个例子。Laravel 尝试将模型实例名称Product $product与 URI 段名称匹配{product}如果找到匹配项,则将 Product 模型的一个实例注入到控制器操作中。如果数据库没有产品,则返回 404 错误。最终结果与以前相同,但代码更少。

打开 POSTMAN,产品的端点应该可以工作。确保您已 Accept : application/json启用标题。 

验证和异常处理

如果您前往一个不存在的资源,这就是您将看到的。 

使用Laravel RESTful后端构建React应用程序:第1部分(Laravel 5.5 API)  第3张

NotFoundHTTPException就是 Laravel 显示 404 错误的方式。如果您希望服务器返回 JSON 响应,则必须更改默认的异常处理行为。Laravel 有一个专门用于异常处理的 Handler 类,位于app/Exceptions/Handler.php该类主要有两个方法:report()render()report方法用于报告和记录异常事件,而 render 方法用于在遇到异常时返回响应。更新 render 方法以返回 JSON 响应:

应用程序/异常/Handler.php

public function render($request, Exception $exception)
  {
    
      if ($exception instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) 
      {
       return response()->json([
            'message' => 'Resource not found'
        ], 404);
      }
      
      return parent::render($request, $exception);
  }

Laravel 还允许我们使用一组验证规则来验证传入的 HTTP 请求,并在验证失败时自动返回 JSON 响应。验证的逻辑将放置在控制器内。该 Illuminate\Http\Request对象提供了一个 validate 方法,我们可以使用它来定义验证规则。让我们在 store 方法中添加一些验证检查。

app/HTTP/Controllers/ProductsController.php

public function store(Request $request)
    {
		$this->validate($request, [
        'title' => 'required|unique:products|max:255',
        'description' => 'required',
        'price' => 'integer',
        'availability' => 'boolean',
    ]);
	    $product = Product::create($request->all());

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

概括

我们现在有一个适用于产品列表应用程序的 API。但是,该 API 缺乏基本功能,例如身份验证和限制未经授权用户的访问。Laravel 对身份验证具有开箱即用的支持,并且为其构建 API 相对容易。我鼓励您实施身份验证 API 作为练习。 


文章目录
  • 介绍
    • 为什么选择 Laravel 和 React?
  • 先决条件
  • 安装和设置你的 Laravel 项目
  • 配置环境
  • 了解模型、路由和控制器
  • 路由器
      • 路线/api.php
  • 产品型号
      • 数据库/迁移/timestamp_create_products_table.php
      • 应用程序/产品.php
  • 数据库播种
      • 数据库/种子/ProductsTableSeeder.php
      • 路线/api.php
  • 控制器
      • app/HTTP/Controllers/ProductsController.php
      • 路线/api.php
  • 验证和异常处理
      • 应用程序/异常/Handler.php
      • app/HTTP/Controllers/ProductsController.php
  • 概括