zoukankan      html  css  js  c++  java
  • laravel和dingoapi的结合使用

    dingoapi是一个laravel的开源插件,可以在github上搜索到,现在在做一个项目,项目中总是会有后端跟前端的json数据交互,而这个dingoapi为json交互提供了很大的便利。

    先安装dingoapi

    1、在composer.json中的require中添加"dingo/api": "1.0.*@dev",然后在项目根目录运行composer update

    注意:dingoapi如果直接用composer require dingo/api:1.0.x@dev的方式安装是安装不成功的,

    因为这个包作者本人还是将其设置为开发中,非稳定版,但是实际上这个包经过验证是稳定的,已经有4500+的star了。

    2、在config/app.php中注册服务提供者到providers

    DingoApiProviderLaravelServiceProvider::class,

    3、生成dingoapi的配置文件

    php artisan vendor:publish --provider="DingoApiProviderLaravelServiceProvider"

    会在config文件夹里生成api.php这个配置文件

    4、将api.php中的prefix默认值设置为api,也可以不是api,但是必须要有个后缀,后缀不要设置为"/",如果设置为"/",laravel的视图跟api会弄混淆,比如,在laravel中自定义了一个404错误页面,如果这里设置为"/"的话,访问不存在的页面的时候,会返回格式为json的错误信息,因为dingapi就是做接口用的,不管什么都会被转为json。

    那如果想把视图跟api区分开来,路由文件需要这么写,以下是例子:

    <?php
    
    /*
    |--------------------------------------------------------------------------
    | Web Routes
    |--------------------------------------------------------------------------
    |
    | This file is where you may define all of the routes that are handled
    | by your application. Just tell Laravel the URIs it should respond
    | to using a Closure or controller method. Build something great!
    |
    */
    Route::post('/test','AdminController@test');
    Route::post('/hook','HookController@hook');
    #后台管理系统登录视图
    Route::get('/admin','AdminController@loginView');
    Route::get('/admin/login','AdminController@loginView');
    #后台管理系统登录api
    Route::post('/admin/login','AdminController@login');
    #退出登录api
    Route::get('/logout','UserController@logout');
    #管理员可见视图
    Route::group(['middleware' => ['role:admin']], function () {
        #用户列表视图
        Route::get('/users','AdminController@users');
        #添加用户视图
        Route::get('/add_user','AdminController@addUserView');
        #机修列表视图
        Route::get('/mechanics_list','MechanicsController@dataList'); 
        #配件列表视图
        Route::get('/parts_list','PartsController@dataList'); 
        #添加配件视图
        Route::get('/add_part','PartsController@addView');
        Route::match(['get','post'],'/mechanics_add', 'MechanicsController@add');
        Route::get('/edit_user/{id}','AdminController@editUserView');
        Route::get('/video',function(){
            return view('video',['title'=>"视频播放"]);
        });
    });
    
    
    $api = app('DingoApiRoutingRouter');
    $api->version('v1', function ($api) {
        $api->group(['namespace' => 'AppHttpControllersApi'], function ($api) {
    //namespace声明路由组的命名空间,因为上面设置了"prefix"=>"api",所以以下路由都要加一个api前缀,比如请求/api/users_list才能访问到用户列表接口
    $api->group(['middleware'=>['role:admin']], function ($api) { #管理员可用接口 #用户列表api $api->get('/users_list','AdminApiController@usersList'); #添加用户api $api->post('/add_user','AdminApiController@addUser'); #编辑用户api $api->post('/edit_user','AdminApiController@editUser'); #删除用户api $api->post('/del_user','AdminApiController@delUser'); #上传头像api $api->post('/upload_avatar','UserApiController@uploadAvatar'); }); }); });

    需要新建一个BaseController:

    <?php
    
    namespace AppHttpControllersApi;
    
    use DingoApiRoutingHelpers;
    use AppHttpControllersController;
    
    class BaseController extends Controller
    {
        use Helpers;
    }

    然后做接口的控制器都继承这个BaseController

    这些做接口的控制器放Api文件夹里

    然后如果用了Requests做验证,需要将原本request里的use IlluminateFoundationHttpFormRequest换成use DingoApiHttpFormRequest;

    不然的话不能明确的显示验证错误的消息。

    以下是我用到dingoapi的一些功能:

    第一个功能:

    当我用jquery的ajax请求服务器的数据的时候,ajax其实有两个参数,success的回调函数和error的回调函数,在laravel中,如果我直接return响应一个数组,laravel框架会自动的将这个数组变成json格式的响应,所以我在laravel代码写类似下面的代码:

    if($error){
        return ['status'=>'error',''=>'message'=>'未通过验证'];    //返回200响应码,但是返回status为error的标识
    
    }
    return ['status'=>'success',''=>'message'=>'操作成功'];      //返回200响应码,并且返回status为success的标识

    这个时候前端jquery的success的回调函数可以根据status这个标识来判断操作是否成功:

    dataType:'json',          //注意这里要写json,标识服务器返回的是json,jquery会将这个json字符串转化为json对象方便下面获取数据
    success:function(res){
         if(res.status == 'error'){
        alert(res.message);    //这里会alert一个“未通过验证”
       }
       else{
         alert(res.message);   //这里会alert一个“操作成功”
       }
    
    }

    这样是一种前端跟后端传递数据的方法,不管操作成功或者失败都返回200的正确响应,根据status来判断操作成功或者失败。

    如果我使用dingoapi的话,dingoapi可以既返回异常又返回json数据(如果不使用dingoapi,返回异常的话会返回一个异常的html页面)。

    所以就可以用jquery的ajax的error回调函数来肯定操作失败的行为:

    dataType:json,

    error:function(error){

      alert($.parseJSON(error.responseText));    //parseJSON方法将json字符串转化为json对象

    }

        这里是laravel控制器中的一个方法。

            这里是ajax的error回调函数

    这里是浏览器的控制台


    看完效果以后便知道为什么要用parseJSON将json字符串转化为json对象了,因为responseText的属性是一个json格式的字符串,但不是对象。

    转化为对象以后变会输出错误消息。

    第二个功能:

    使用dingoapi的tranform

    appHttpTransformers下新建一个UserTransformer.php文件(这个Transformers文件夹也是新建的):

    <?php
    
    namespace AppHttpTransformers;
    
    use AppModelsUser;
    use LeagueFractalTransformerAbstract;
    
    class UserTransformer extends TransformerAbstract
    {
    
        protected $availableIncludes = [];
        protected $defaultIncludes = [];
    
        public function transform(User $item)
        {
            return [
                    'id' => $item->id,
                    'name' => $item->name,
                    'sex' => $item->sex,
                    'telphone' => $item->telphone,
                    'car_company'=>isset($item->car->car_company) ? $item->car->car_company : '',
                    'license_plate'=>isset($item->car->license_plate) ? $item->car->license_plate : '',
                    'birthday' => $item->birthday,
                    'created_at'=>(string)$item->created_at,
                    'first_time'=>isset($item->car->first_time) ? $item->car->first_time : '',
                    'integral'=>$item->integral,
            ];
        }
    
    }

    这样定义以后,在控制中

    
    

    <?php

    
    

    namespace AppHttpControllersApi;

    use AppModelsUser;

    use AppHttpTransformersUserTransformer;

    class UserApiController extends BaseController  //这里继承BaseController

    {

      public function users(){  

        $user->all();    //这里也可以写成一些where条件
        return $this->response->collection($user, new UserTransformer);

      }

    }

    
    

    这就会把$user里其他的字段全部过滤掉,这么写的话非常有规范性,控制器中就不用写太多的数据转化了。

    当然如果非要在控制中实现过滤数组的话,可以使用以下常用函数:

    array_filter($arr)  

    参数是一个数组,实现过滤键值为空的数组元素

    array_only($arr,$key) 参数是数组,只保留参数数组中的键,其余的全部过滤掉

    array_except($arr,$key)参数是数组,除了参数$key数组以外的键,其余的全部过滤掉

    当然,dingoapi的功能肯定不只这两个,还有很多,我会慢慢在使用中做笔记。

  • 相关阅读:
    wcf第3步之报文分析及原生调用
    IBatis 批量插入数据之SqlBulkCopy
    MVC前后端数据被编码
    log4Net控制台输出
    这可能是由于服务终结点绑定未使用 HTTP 协议造成的 .这还可能是由于服务器中止了 HTTP 请求上下文
    IBatis存储过程返回值
    路由学习2
    restClient访问SSL
    hibernate多对多关系配置
    hibernate 一对多操作(级联操作)
  • 原文地址:https://www.cnblogs.com/zzdylan/p/6002503.html
Copyright © 2011-2022 走看看