阿北的知識分享小程序中restful使用經驗貼

你們知道我最近在給「阿北的知識分享」微信小程序改版,使用的是yii2中的restful功能,接下來把遇到的一些問題及小技巧分享一下。

先安利一下小程序碼 連接javascript

開始分享。php

URL要重寫

咱們知道restful風格的url通常是這樣的java

  • GET /users
  • POST /users
  • DELETE /users/1

咱們yii2默認的url形式是index.php?r=controller/action。nginx

雖說yii2已經提供了專門針對於restful的路由規則,可是咱們仍是須要服務器支持url重寫把index.php去掉。web

我用的是nginx,以下配置apache

location / {
    if (!-e $request_filename){
        rewrite ^/(.*) /index.php last;
    }
}

若是你的是apache能夠以下配置json

// Apache須要支持url重寫其AllowOverride爲all
AllowOverride:all

//web目錄下增長.htaccess,隱藏index.php文件 內容以下
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php

小程序

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\?*$ index.php/$1 [L,QSA]

不要DELETE了

默認狀況下yii2的restful已經提供了index、view、update、create和delete共5個action來知足於對資源的不一樣行爲。可能你的接口中不須要delete,有兩個方法微信小程序

url規則中配置(推薦)
好比我不但願開放 DELETE /users/1 則能夠配置對應的url規則以下服務器

[
    'class' => 'yii\rest\UrlRule',
    'controller' => 'user',
    'except'=>['delete']
],

重寫action
咱們知道這些內置方法使用了actions方法實現,咱們能夠複寫這個函數。

class UserController extends ActiveController {
    public $modelClass = 'app\models\User';

    public function actions() {
        $actions = parent::actions();
        unset($actions['delete']);
        return $actions;
    }

    ...
}

兩種方法均可以實現可是返回結果不相同,感興趣的同窗能夠本身體驗下。

加個action叫abc

內置方法知足了不少,需求太複雜我想本身在控制器裏增長一個actionAbc的方法,如何配置那?看下面的代碼,仍是在urlManager裏搞定。

[
    'class' => 'yii\rest\UrlRule',
    'controller' => 'user',
    'except'=>['delete','update','index'],
    'extraPatterns'=>[
        'POST abc'=>'abc',
    ]
],

這樣你就能夠經過 POST /users/abc 來調用User控制器的abc Action了。

我要更多數據

我想經過 GET /users 獲取會員的id和nickname字段,很簡單在get參數中傳入fields='id,nickname',這很容易畢竟id和nickname就是user表的列,可是我還想得到每一個會員下的訂單數,而訂單數並不屬於user表,方法以下

增長get參數
咱們須要增長一個叫作expand的參數,值爲你要獲取的字段名字,逗號分隔每個。

GET /users?fields='id,nickname'&expand='oTotal'

配置user模型
咱們須要重寫一個叫作extraFields的方法

public function extraFields() {
    return [
        'oTotal'
    ];
}

編寫具體邏輯
接下來咱們要在User模型中編寫實現oTotal的函數

public function getOTotal(){
    return Order::find()->where(['user_id'=>$this->id])->count();
}

你發現了什麼?你是否記起了在yii2中一個叫作關聯的概念,你是否發現獲取多種數據變得很簡單了?

json怎麼病了

使用小程序發起服務器請求,好比新建一本書,咱們通常喜歡編寫以下代碼

wx.request({
    method: 'POST',
    data: {
        name: name
    },
    url: app.globalData.remoteUrl + '/books',
    header: {
        'content-type': 'application/json'
    },
    success: function (res) {
        
    }
})

這裏我設置了'content-type': 'application/json',問題發生了,我在服務器端沒法獲取json中的name值。

很簡單,默認狀況下yii2的restful並不支持對請求中json的數據解析,還好小小配置下就能夠了。

// config/web.php
'components' => [
    'request' => [
        'cookieValidationKey' => '',
        'parsers' => [
            'application/json' => 'yii\web\JsonParser',
        ]
    ],
]

增長一個JsonParser解析器就能夠了。

認證問題

網頁上有登陸,可是restful上沒有session,不要緊咱們可使用access token來搞定,配置很簡單。
好比我如今要求GET /users 必須是登錄後訪問。

配置user模型和表
首先爲user表配置一個access_token字段,同時在User模型下作一個generateAccessToken方法

public function generateAccessToken(){
    $this->access_token = Yii::$app->security->generateRandomString();
}

該方法主要用於生成access_token值。

固然咱們的User模型須要實現 yiiwebIdentityInterface 接口,不然使用Yii::$app->user沒法訪問的,關於IdentityInterface我想在yii2登陸這裏已經很熟悉了,記住restful的認證若是生效還要實現以下方法

public static function findIdentityByAccessToken($token, $type = null)
{
    $model = User::find()->where(['access_token'=>$token])->one();
    return $model;
}

到這裏User模型就配置好了,小提醒:若是你想作一些登陸那一刻的事兒,能夠也放到findIdentityByAccessToken,好比記錄登陸時間啥的。

配置action
接下來咱們來對具體的接口進行認證限制,複寫behaviors行爲,以下

use yii\filters\auth\HttpBearerAuth;
class UserController extends ActiveController {
    public $modelClass = "app\models\User";

    public function behaviors() {

        $behaviors = parent::behaviors();
        $behaviors['contentNegotiator']['formats'] = ['application/json'=>Response::FORMAT_JSON];

        $behaviors['authenticator'] = [
            'class'=>HttpBearerAuth::className(),
            'only'=>[
                'index'
            ],
        ];

        return $behaviors;
    }
}

這樣就搞定了,咱們這裏用的是HttpBearerAuth認證,就是在請求的header裏面寫Authorization,yii2的restful還支持其餘的。記住這個認證過程是自動的,而且咱們在認證的方法裏可使用Yii::$app->user->id獲取當前會員的ID。

列表更多參數

咱們知道經過 GET /users 能夠得到會員列表,可是你可能說我要獲取來自於微信平臺的會員(user表裏有一個字段plat表明來源平臺),怎麼辦?

咱們須要從新編寫該接口並接受plat參數,在User控制器中先設置新的prepareDataProvider函數,它用來接收參數並生成會員列表數據,返回的是一個ActiveDataProvider結果集。

namespace app\modules\xcx\controllers;

use Yii;
use yii\rest\ActiveController;
....

class UserController extends ActiveController {
    public $modelClass = 'app\models\User';

    public function actions() {
        $actions = parent::actions();
        $actions['index']['prepareDataProvider'] = [$this,'prepareDataProvider'];
        return $actions;
    }

    public function prepareDataProvider(){
        $params = Yii::$app->request->queryParams;

        $modelClass = $this->modelClass;
        $query = $modelClass::find()->where(['plat'=>$params['plat']]);

        $provider = new ActiveDataProvider([
            'query'=>$query->orderBy(['created_at'=>SORT_DESC])
        ]);

        return $provider;
    }

}

首先經過 $actions['index']['prepareDataProvider'] = [$this,'prepareDataProvider'] 告訴yii2我要自定義獲取結果集的方法,接下來定義這個方法,在prepareDataProvider裏能夠經過Yii::$app->request->queryParams 接收過來的get參數的值。

小結

以上就是目前爲止在使用yii2的restful開發小程序時候使用的一些知識和技巧,但願對你有用,之後若是有再分享哈。

相關文章
相關標籤/搜索