laravel5.1开发api

谭佳成
2018-09-21
(47)

初始化,创建表、模型、控制器

php artisan make:migration create_lessons_table --create=lessons
php artisan make:model Lesson
php artisan make:controller LessonsController
php artison migrate

生成测试数据

在database/factories/modelfoctory.php添加

$factory->define(App\Lesson::class, function (Faker\Generator $faker) {
 return [
 'title' => $faker->sentence,
 'body' => $faker->paragraph,
 'free' => $faker->boolean()
];
});

php artisan tinker
namespace App;
factory(Lesson::class,60)->create();

配置路由

Route:group(['prefix'=>'api/v1'],function(){
   Route::resource('lessons','LessonsController');
})

无验证完整版

实现访问http://host/api/v1/lessons得到列表
访问http://host/api/v1/lessons/1得到id为1的数据,注:host为虚拟主机段

  • App\Http\Controllers\LessonsController.php

<?php

namespace App\Http\Controllers;

use App\Lesson;
use App\Transformer\LessonTransformer;
use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

class LessonsController extends ApiController
{
   protected $lessonTransformer;

   /**
    * LessonsController constructor.
    * @param $lessonTransformer
    */
   public function __construct(LessonTransformer $lessonTransformer) {
       $this->lessonTransformer = $lessonTransformer;
   }


   /**
    * Display a listing of the resource.
    *
    * @return \Illuminate\Http\Response
    */
   public function index()
   {
       //all();
       //没有提示信息
       //直接展示数据结构
       //没有错误细腻
//        return Lesson::all();
       $lessons = Lesson::all();
       return $this->response([
              'status' => 'success',
              'data' => $this->lessonTransformer->transformCollection($lessons->toArray())
       ]);
   }

   /**
    * Show the form for creating a new resource.
    *
    * @return \Illuminate\Http\Response
    */
   public function create()
   {
       //
   }

   /**
    * Store a newly created resource in storage.
    *
    * @param  \Illuminate\Http\Request  $request
    * @return \Illuminate\Http\Response
    */
   public function store(Request $request)
   {
       dd($request);
   }

   /**
    * Display the specified resource.
    *
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   public function show($id)
   {
       $lesson = Lesson::find($id);
       if(!$lesson){
           return $this->responseNotFound();
       }
       return $this->response([
           'status' => 'success',
           'data' => $this->lessonTransformer->transForm($lesson)
       ]);
   }

   /**
    * Show the form for editing the specified resource.
    *
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   public function edit($id)
   {
       //
   }

   /**
    * Update the specified resource in storage.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   public function update(Request $request, $id)
   {
       //
   }

   /**
    * Remove the specified resource from storage.
    *
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   public function destroy($id)
   {
       //
   }

}
  • App\Http\Controllers\ApiController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

class ApiController extends Controller
{
   public $statusCode = 200;

   /**
    * @return int
    */
   public function getStatusCode() {
       return $this->statusCode;
   }


   /**
    * @param $statusCode
    * @return $this
    */
   public function setStatusCode($statusCode) {
       $this->statusCode = $statusCode;
       return $this;
   }

   public function responseNotFound($msg = 'not found!')
   {
       return $this->setStatusCode(404)->responseError($msg);
   }

   public function responseError($msg){
       return $this->response([
           'status' => 'not found',
           'error' => (object)[
               'status_code' => $this->getStatusCode(),
               'message' => $msg
           ]
       ]);
   }

   public function response($data)
   {
       $data['status_code'] = $this->getStatusCode();
       return \Response::json($data);
   }



}
  • App\Transformer\Transformer.php

<?php


namespace App\Transformer;


/**
* Class Transformer
* @package App\Transformer
*/
abstract class Transformer {
   public function transformCollection($items){
       return array_map([$this, 'transForm'], $items);
   }

   abstract public function transForm($item);
}
  • App\Transformer\LessonTransformer.php

<?php


namespace App\Transformer;


/**
* Class LessonTransformer
* @package App\Transformer
*/
class LessonTransformer extends Transformer {
   public function transForm($item)
   {
       return [
           'id' => $item['id'],
           'title' => $item['title'],
           'content' => $item['body'],
           'is_free' => (boolean)$item['free']
       ];
   }
}

Basic Auth进行请求API的用户认证

  • tinker创建用户

php artisan tinker
App\User::create(['name'=> 'tjc', 'email'=>'952243214@qq.com','password'=>bcrypt('123456')]);

  • 使用postman模拟post请求

  • 注释App\Http\Kernel.php 属性$middleware数组里\App\Http\Middleware\VerifyCsrfToken::class

  • 注册auth.bash
    在App\Http\Controllers\LessonsController.php构造函数添加

$this->middleware('auth.basic',['only'=>['store','update']]);

  • 修改App\Http\Controllers\LessonsController.php store方法

public function store(Request $request)
{
   if(! $request->get('title') || ! $request->get('body')){
       return $this->setStatusCode(422)->responseError('validate fails!');
   }
   Lesson::create($request->all());
   return $this->setStatusCode(201)->response([
       'status' => 'success',
       'msg' => 'lessons created!'
   ]);
}
  • postman 填写用户名密码,body填写title和body值,发送->ok

引入Dingo API和JWT

使用Dingo

  • 配置env

API_STANDARDS_TREE=vnd 
API_PREFIX=api
API_VERSION=v1
API_DEBUG=true
  • 修改config\api.php

'auth' => [
   'basic' => function($app){
        return new Dingo\Api\Auth\Provider\Basic($app['auth']);
   },
   'jwt' => function($app){
       return new Dingo\Api\Auth\Provider\JWT($app['Tymon\JWTAuth\JWTAuth']);
   }
],
  • 编辑路由

$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api) {
   $api->group(['namespace' => 'App\Api\Controllers'], function ($api) {
       $api->get('lessons','LessonsController@index');//访问App\Api\Controllers\LessonsController的index方法
   });
});
  • 创建目录、文件夹
    dir Api
    dir Controllers
    file LessonsController.php

  • 创建App\Api\Controllers\BaseController.php

<?php


namespace App\Api\Controllers;


use App\Http\Controllers\Controller;
use Dingo\Api\Routing\Helpers;

class BaseController extends Controller {
   use Helpers;
}
  • LessonsController.php

<?php


namespace App\Api\Controllers;


use App\Api\Transformer\LessonTransformer;
use App\Lesson;

class LessonsController extends  BaseController {

   public function index()
   {
       $lessons = Lesson::all();
       return $this->collection($lessons,new LessonTransformer());
   }
}
  • 创建Transformer文件夹、LessonTransformer.php文件

  • LessonTransformer.php

<?php


namespace App\Api\Transformer;


use App\Lesson;
use League\Fractal\TransformerAbstract;

class LessonTransformer extends TransformerAbstract {
   public function transform(Lesson $lesson)
   {
       return [
           'id' => $lesson['id'],
           'title' => $lesson['title'],
           'content' => $lesson['body'],
           'is_free' => (boolean)$lesson['free']
       ];
   }
}
  • 访问http://host/api/lessons -> ok

jwt(json web token)

  • 配置$routeMiddleware,在http\kernel.php

protected $routeMiddleware = [
   'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
   'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
   'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
];
<?php


namespace App\Api\Controllers;
use App\User;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;

use Illuminate\Http\Request;

/**
* Class AuthController
* @package App\Api\Controllers
*/
class AuthController extends BaseController {

   /**
    * @param Request $request
    * @return \Illuminate\Http\JsonResponse
    */
   public function authenticate(Request $request)
   {
       // grab credentials from the request
       $credentials = $request->only('email', 'password');

       try {
           // attempt to verify the credentials and create a token for the user
           if (! $token = JWTAuth::attempt($credentials)) {
               return response()->json(['error' => 'invalid_credentials'], 401);
           }
       } catch (JWTException $e) {
           // something went wrong whilst attempting to encode the token
           return response()->json(['error' => 'could_not_create_token'], 500);
       }

       // all good so return the token
       return response()->json(compact('token'));
   }

   /**
    * @param Request $request
    * @return \Illuminate\Http\JsonResponse
    */
   public function register(Request $request)
   {
       $newUser = [
           'email' => $request->get('email'),
           'name' => $request->get('name'),
           'password' => bcrypt($request->get('password'))
       ];
       $user = User::create($newUser);
       $token = JWTAuth::fromUser($user);
       return response()->json(compact('token'));
   }

}
  • 配置路由

$api->version('v1', function ($api) {
   $api->group(['namespace' => 'App\Api\Controllers'], function ($api) {
       $api->post('user/login','AuthController@authenticate');
       $api->post('user/register','AuthController@register');
       $api->group(['middleware' => 'jwt.auth'], function ($api) {
           $api->get('lessons','LessonsController@index');
           $api->get('lessons/{id}','LessonsController@show');
       });

   });
});
  • 修改LessonsController.php

<?php


namespace App\Api\Controllers;


use App\Api\Transformer\LessonTransformer;
use App\Lesson;

/**
* Class LessonsController
* @package App\Api\Controllers
*/
class LessonsController extends  BaseController {

   /**
    * @return mixed
    * @throws \ErrorException
    */
   public function index()
   {
       $lessons = Lesson::all();
       return $this->collection($lessons,new LessonTransformer());
   }

   /**
    * @param $id
    * @throws \ErrorException
    */
   public function show($id)
   {
       $lesson = Lesson::find($id);
       if(!$lesson){
           return $this->response->errorNotFound('lesson not found!');
       }
       return $this->item($lesson,new LessonTransformer());
   }
}
  • 模拟请求
    使用postman,post请求http://host/api/user/login,请求body中传递邮箱和密码,得到$token
    再次访问http://host/api/lesson?token=$token  ->ok

  • 根据token获取用户信息
    新增路由:

$api->group(['middleware' => 'jwt.auth'], function ($api) {
   $api->get('user/me','AuthController@getAuthenticatedUser');//add
   $api->get('lessons','LessonsController@index');
   $api->get('lessons/{id}','LessonsController@show');
});
  • 编辑AuthController.php,新增方法getAuthenticatedUser,注意头部use三个异常类
    use Tymon\JWTAuth\Exceptions\JWTException;
    use Tymon\JWTAuth\Exceptions\TokenExpiredException;
    use Tymon\JWTAuth\Exceptions\TokenInvalidException;

public function getAuthenticatedUser()
{
try {

   if (! $user = JWTAuth::parseToken()->authenticate()) {
       return response()->json(['user_not_found'], 404);
   }

} catch (TokenExpiredException $e) {

   return response()->json(['token_expired'], $e->getStatusCode());

} catch (TokenInvalidException $e) {

   return response()->json(['token_invalid'], $e->getStatusCode());

} catch (JWTException $e) {

   return response()->json(['token_absent'], $e->getStatusCode());

}

// the token is valid and we have found the user via the sub claim
return response()->json(compact('user'));
}
  • 访问http://host/api/user/me?token=登录获取到的token


如无说明,本站文章均为原创,转载或引用注明来源:https://93jc.cn/article/170.html