หลังจากที่ได้ลองทำการสร้าง api ด้วย laravel ภาคหนึ่งไปแล้ว เราลองมาทำให้มันยากขึ้นกันดีกว่า
ก่อนอื่นผมขอออกตัวไว้ก่อนว่าเน้นให้เห็นภาพรวมก่อน แล้วบทต่อไปผมจะไปเจาะลึกที่ละเนื้อหาครับ
เอาล่ะสำหรับท่านที่ยังไม่ได้ติดตั้ง Laravel ก็ทำการติดตั้งให้เรียบร้อยครับ
Library ที่จะให้
- Prettus\Repository
- Teepluss\Restable
- Benchmark
วิธีการติดตั้ง Prettus Repository คลิ๊กได้ตามลิงค์ครับ สำหรับวิธีการติดตั้ง Restable สามารถทำได้ดังนี้
- install ผ่าน composer โดยใช้คำสั่ง
composer require teepluss/restable - รอสักครู่เพื่อให้ Package ดาวโหลดจนเสร็ดแล้วทำการแก้ไขไฟล์ app.php โดยเพิ่ม
providerTeepluss\Restable\RestableServiceProvider::class,
'Restable' => Teepluss\Restable\Facades\Restable::class,
Library Teepluss\Restable ตัวนี้เพื่อเป็นตัวกลางการ Response handle ครับซึ่งใช้งานได้สะดวกมาก สามารถเรียกใช้งานจากไฟล์ไหนก็ได้ ภายหลังจากการ Load เพราะว่าเป็น Facade ครับ
Library Benchmark สำหรับตัวนี้เอาไว้เพื่อจับเวลาตามชื่อเลยครับ สำหรับการติดตั้งทำได้โดย สร้างไฟล์ตามนี้ครับ
Library Benchmark สำหรับตัวนี้เอาไว้เพื่อจับเวลาตามชื่อเลยครับ สำหรับการติดตั้งทำได้โดย สร้างไฟล์ตามนี้ครับ
namespace App\Libraries; class Benchmark { /** * List of all benchmark markers and when they were added * * @var array */ public $marker = array(); // -------------------------------------------------------------------- /** * Set a benchmark marker * * Multiple calls to this function can be made so that several * execution points can be timed * * @access public * @param string $name name of the marker * @return void */ public function mark($name) { $this->marker[$name] = microtime(); } // -------------------------------------------------------------------- /** * Calculates the time difference between two marked points. * * If the first parameter is empty this function instead returns the * {elapsed_time} pseudo-variable. This permits the full system * execution time to be shown in a template. The output class will * swap the real value for this variable. * * @access public * @param string a particular marked point * @param string a particular marked point * @param integer the number of decimal places * @return mixed */ public function elapsed_time($point1 = '', $point2 = '', $decimals = 4) { if ($point1 == '') { return '{elapsed_time}'; } if (!isset($this->marker[$point1])) { return ''; } if (!isset($this->marker[$point2])) { $this->marker[$point2] = microtime(); } list($sm, $ss) = explode(' ', $this->marker[$point1]); list($em, $es) = explode(' ', $this->marker[$point2]); return number_format(($em + $es) - ($sm + $ss), $decimals); } // -------------------------------------------------------------------- /** * Memory Usage * * This function returns the {memory_usage} pseudo-variable. * This permits it to be put it anywhere in a template * without the memory being calculated until the end. * The output class will swap the real value for this variable. * * @access public * @return string */ public function memory_usage() { return '{memory_usage}'; } }Route
Route::group(['namespace' => 'Api\v1\Member', 'prefix' => 'api/v1/member', 'middleware' => ['guest']], function () { Route::get('/', [ 'uses' => 'MembersController@index', 'as' => 'member.MembersController.index', ]); Route::post('/', [ 'uses' => 'MembersController@store', 'as' => 'member.MembersController.store', ]); });Controllers
namespace App\Http\Controllers\Api\v1\Member; use App\Http\Controllers\Api\v1\Member\BaseApiController; use App\Http\Requests\MemberRequest; use App\Repositories\MembersRepository; use Illuminate\Http\Request; class MembersController extends BaseApiController { /** * [$request description] * @var [type] */ private $request; /** * [$member description] * @var [type] */ private $member; public function __construct(MemberRequest $request, MembersRepository $member) { parent::__construct(); $this->request = $request; $this->member = $member; } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { try { $member['item'] = $this->member->all(); if (!empty($member)) { $all = $member['item']->count(); return $this->response(200, $member, '', $all, $all); } else { return $this->response(404, []); } } catch (\Exception $e) { return $this->response(400, [], $e->getMessage()); } } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { try { $insert['item'] = $this->member->create(\Input::all()); if ($insert) { return $this->response(200, $insert, '', 1, 1); } else { return $this->response(400, ['insert fail']); } } catch (\Exception $e) { return $this->response(400, [], $e->getMessage()); } } }Request
namespace App\Http\Requests; use App\Http\Requests\Request; class MemberRequest extends Request { /** * 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() { $rules = []; switch ($this->method()) { case 'POST': $rules = [ 'name' => 'required|string|min:3|max:60', 'email' => 'required|string|email|unique:users,email', 'password', 'remember_token', 'created_at' => 'date|date_format:Y-m-d H:i:s', 'updated_at' => 'date|date_format:Y-m-d H:i:s', ]; break; default: # code... break; } return $rules; } }BaseControllers
namespace App\Http\Controllers\Api\v1\Member; use App\Http\Controllers\Controller; use App\Libraries\Benchmark; class BaseApiController extends Controller { public $benchmark; public static $listCode = array( '200' => 'OK', '201' => 'Created', '202' => 'Accepted', '203' => 'Non-Authoritative Information', '204' => 'No Content', '205' => 'Reset Content', '206' => 'Partial Content', '300' => 'Multiple Choices', '301' => 'Moved Permanently', '302' => 'Found', '303' => 'See Other', '304' => 'Not Modified', '306' => 'Switch Proxy', '307' => 'Temporary Redirect', '308' => 'Resume Incomplete', '400' => 'Bad Request', '401' => 'Unauthorized', '402' => 'Payment Required', '403' => 'Forbidden', '404' => 'Not Found', '405' => 'Method Not Allowed', '406' => 'Not Acceptable', '407' => 'Proxy Authentication Required', '408' => 'Request Timeout', '409' => 'Conflict', '410' => 'Gone', '411' => 'Length Required', '412' => 'Precondition Failed', '413' => 'Request Entity Too Large', '414' => 'Request-URI Too Long', '415' => 'Unsupported Media Type', '416' => 'Requested Range Not Satisfiable', '417' => 'Expectation Failed', '500' => 'Internal Server Error', '501' => 'Not Implemented', '502' => 'Bad Gateway', '503' => 'Service Unavailable', '504' => 'Gateway Timeout', '505' => 'HTTP Version Not Supported', '511' => 'Network Authentication Required', ); public function __construct() { $this->benchmark = new Benchmark; $this->benchmark->mark('start'); } public function response($code = 400, $data = '', $errorMessage = null, $total = 0, $total_page = 0) { if ($code == '0') { $code = 400; } $header = array( 'code' => $code, 'message' => self::$listCode[$code], ); $response = array( 'header' => $header, 'transaction_id' => (isset($transaction_id)) ? $transaction_id : '105116109 ' . DATE('U'), 'total' => $total, 'total_page' => $total_page, 'count_result' => (isset($data['item'])) ? count($data['item']) : 0, 'date_current' => date('Y-m-d H:i:s'), ); $request = \Request::all(); $responseReturn = array_merge($response, $request); if ($response['header']['code'] == 200) { $responseReturn['data'] = $data; } else { $responseReturn['data'] = null; $responseReturn['debug_error_message'] = $errorMessage; } $this->benchmark->mark('end'); $responseTime = $this->benchmark->elapsed_time('start', 'end'); $responseReturn['process_time'] = $responseTime; return \Restable::listing($responseReturn)->render('json'); } }MemberRepository interface
namespace App\Repositories; use Prettus\Repository\Contracts\RepositoryInterface; /** * Interface MembersRepository * @package namespace App\Repositories; */ interface MembersRepository extends RepositoryInterface { // }MemberRepo
namespace App\Repositories; use Prettus\Repository\Eloquent\BaseRepository; use Prettus\Repository\Criteria\RequestCriteria; use App\Repositories\MembersRepository; use App\Entities\Members; /** * Class MembersRepositoryEloquent * @package namespace App\Repositories; */ class MembersRepositoryEloquent extends BaseRepository implements MembersRepository { /** * Specify Model class name * * @return string */ public function model() { return Members::class; } /** * Boot up the repository, pushing criteria */ public function boot() { $this->pushCriteria(app(RequestCriteria::class)); } } }Member model
namespace App\Entities; use Illuminate\Database\Eloquent\Model; use Prettus\Repository\Contracts\Transformable; use Prettus\Repository\Traits\TransformableTrait; class Members extends Model implements Transformable { use TransformableTrait; protected $table = 'users'; protected $fillable = [ 'name', 'email', 'password', 'remember_token', 'created_at', 'updated_at', ]; protected $hidden = [ 'password', 'remember_token', ]; }VerifyCsrf
namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier; class VerifyCsrfToken extends BaseVerifier { /** * The URIs that should be excluded from CSRF verification. * * @var array */ protected $except = [ 'api/v1/member', ]; }Request
namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; abstract class Request extends FormRequest { public function response(array $errors) { $header = array( 'code' => '400', 'message' => 'Bad Request', ); $response = array( 'header' => $header, 'transaction_id' => ($this->has('transaction_id')) ? $this->get('transaction_id') : DATE('U'), 'total' => 0, 'count_result' => 0, 'date_current' => date('Y-m-d H:i:s'), ); $request = $this->all(); $responseReturn = array_merge($response, $request); $responseReturn['data'] = $errors; return \Restable::listing($responseReturn)->render('json'); } }RepositoryProvider
namespace App\Providers; use Illuminate\Support\ServiceProvider; class RepositoryProvider extends ServiceProvider { /** * Bootstrap the application services. * * @return void */ public function boot() { // } /** * Register the application services. * * @return void */ public function register() { $this->app->bind( 'App\Repositories\MembersRepository', 'App\Repositories\MembersRepositoryEloquent' ); } }ผลลัพธ์การดึงขอ้มูล
{ { "header": { "code": 200, "message": "OK" }, "transaction_id": "105116109 1447929847", "total": 7, "total_page": 7, "count_result": 7, "date_current": "2015-11-19 10:44:07", "data": { "item": [ { "id": 1, "name": "xxxx", "email": "sdfsdf@tmail.com", "created_at": "2015-11-19 09:44:06", "updated_at": "2015-11-19 09:44:06" }, { "id": 2, "name": "xxxx", "email": "sdfsdf@tmail.comx", "created_at": "2015-11-19 09:44:24", "updated_at": "2015-11-19 09:44:24" }, { "id": 3, "name": "xxxx", "email": "sdfsdf@tmail.cox", "created_at": "2015-11-19 09:44:55", "updated_at": "2015-11-19 09:44:55" }, { "id": 4, "name": "xxxx", "email": "samark@gmail.com", "created_at": "2015-11-19 09:53:41", "updated_at": "2015-11-19 09:53:41" }, { "id": 5, "name": "samark chai", "email": "samark2@gmail.com", "created_at": "2015-11-19 09:54:58", "updated_at": "2015-11-19 09:54:58" }, { "id": 6, "name": "samark chai", "email": "samark_chai@gmail.com", "created_at": "2015-11-19 09:55:48", "updated_at": "2015-11-19 09:55:48" }, { "id": 7, "name": "samark chai", "email": "samark_chaisa@gmail.com", "created_at": "2015-11-19 09:56:11", "updated_at": "2015-11-19 09:56:11" } ] }, "process_time": "0.0360" }ผลลัทธ์การใส่ข้อมูล
{ "header": { "code": 200, "message": "OK" }, "transaction_id": "105116109 1447926971", "total": 1, "total_page": 1, "count_result": 1, "date_current": "2015-11-19 09:56:11", "name": "samark chai", "email": "samark_chaisa@gmail.com", "data": { "item": { "name": "samark chai", "email": "samark_chaisa@gmail.com", "updated_at": "2015-11-19 09:56:11", "created_at": "2015-11-19 09:56:11", "id": 7 } }, "process_time": "0.0280" }กรณีข้อมูลซ้ำ
{ "header": { "code": "400", "message": "Bad Request" }, "transaction_id": "1447929361", "total": 1, "count_result": 1, "date_current": "2015-11-19 10:36:01", "name": "samark chai", "email": "samark_chaisa@gmail.com", "data": { "email": [ "The email has already been taken." ] } }ในส่วนรายละเอียดจะมาอธิบายภายหลังทีละส่วนครับ
0 ความคิดเห็น:
แสดงความคิดเห็น