由於之前工作都是使用原生 PHP 撰寫網站程式,公司的專案並沒有前後端分離,前後端介接方式與參數都是自己定義,從來沒寫過 RESTful API,在 104 又常看到應徵工作條件要會寫 RESTful API,這是啥技術?? 很難嗎?? 詢問了一下孤狗大神才知道 RESTful API 其實不是技術,是一個撰寫程式風格 style,簡單的說 API 就是前端程式與後端程式溝通的橋梁,REST是撰寫時的一些共通的 Style,這樣好處前端工程師與後端工程師撰寫程式時,有統一的模式。

簡單的說 RESTful API 就是 後端程式根據前端來索取資料時使用相同風格的 URI 並回應相關的資料與狀態碼,回應的資料以 JSON 方式回應,並提供相關的狀態碼給前端。

參考來源: (孤狗大神提供很多相關的資料,僅列出我看的兩三篇)
https://dotblogs.com.tw/jeffyang/2018/04/21/233001
http://www.ruanyifeng.com/blog/2014/05/restful_api.html

牛刀小試

這次拿自己的測試網站來實作一下 RESTful API。簡單的試著撰寫一下 RESTful API.

建立 會員文章的 Route

//Post API
Route::apiResource('posts', 'API\PostController');

建立 會員文章的 API controller

php artisan make:controller API/PostController --api

修改 PostController

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Post as PostEloquent; //posts資料表
use App\PostType as PostTypeEloquent; //post_types資料表
use App\Comment as CommentEloquent; //comments資料表
use Carbon\Carbon; //時間格式套件
use Auth;   //使用者驗證
use Validator; //使用驗證器

class PostController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct()
    {
        //除了 index,show 其餘 function 都要經過 api 的 middleware 檢查
        $this->middleware('api', ['except' => ['index','show']]);
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = PostEloquent::orderBy('created_at','DESC')->paginate(10);
        return response()->json($posts,200);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //檢驗授權是否存在
        $user = auth('api')->user();
        if(!$user){
            return response()->json("授權不存在", 401);
        }

        //驗證資料
        $validator = Validator::make($request->all(), [
            'title'=>'required|string|max:100',
            'type'=>'required|integer|exists:post_types,id',
            'content'=>'required|string|max:5000',
            'onlinedate' => 'date_format:Y-m-d H:i:s',
            'offlinedate' => 'date_format:Y-m-d H:i:s',
        ]);

        //驗證失敗返回訊息
        if ($validator->fails()) {
            return response()->json(['error' => '資料錯誤'], 400);
        }

        //將所有資料收集並儲存,返回儲存的資料及狀態碼
        $post = new PostEloquent($request->all());
        //透過驗證使用者並取得id
        $post->user_id = $user->id;
        //儲存
        $post->save();
        return response()->json($post,200);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $post = PostEloquent::find($id);

        //檢驗該筆資料是否存在
        if (!$post) {
            return response()->json('資料不存在', 404);
        }

        //將資料拋出並提供200狀態碼
        $comments = CommentEloquent::where('post_id',$post->id)->orderBy('created_at','DESC')->paginate(5);
        return response()->json(['post' => $post , 'comments' => $comments], 200);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //檢驗授權是否存在
        $user = auth('api')->user();
        if(!$user){
            return response()->json("授權不存在", 401);
        }

        //資料驗證
        $validator = Validator::make($request->all(), [
            'title'=>'required|string|max:100',
            'type'=>'required|integer|exists:post_types,id',
            'content'=>'required|string|max:5000',
            'onlinedate' => 'date_format:Y-m-d H:i:s',
            'offlinedate' => 'date_format:Y-m-d H:i:s',
        ]);

        //資料驗證失敗返回訊息
        if ($validator->fails()) {
            return response()->json(['error' => '資料檢驗失敗'], 400);
        }

        //檢驗該筆資料是否存在
        $post = PostEloquent::find($id);
        if (!$post) {
            return response()->json(['message' => '資料不存在'], 404);
        }

        //將進來的資料填寫到資料庫後返回修改成功訊息
        $post = PostEloquent::find($id);
        $post->fill($request->all());
        $post->save();
        return response()->json(['message' => '修改成功', 'post' => $post], 200);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //檢驗授權是否存在
        $user = auth('api')->user();
        if(!$user){
            return response()->json("授權不存在", 401);
        }

        //檢驗該筆資料是否存在
        $post = PostEloquent::find($id);
        if (!$post) {
            return response()->json(['message' => '資料不存在'], 404);
        }

        //刪除所有與該筆post相關的資料並返回刪除成功訊息
        $post = PostEloquent::find($id)->delete();
        $comments = CommentEloquent::where('post_id', $id)->delete();
        return response()->json(['message' => '刪除成功'], 200);
    }
}

使用 Postman 測試 API

先登入會員取得 Token
查詢會員文章
查詢單一篇文章及Comments相關資料
透過 API 建立一篇會員文章,必須帶上登入的授權 token 才會生效.
透過 API 修改會員文章內容,必須帶上授權的 token 才會生效
透過 API 刪除會員文章,必須帶上授權 token 才會生效。

註:以上測試只是單純測試,並非完整,其中尚缺少比對文章是否為該使用者所擁有或者有isAdmin權限。

最後修改日期: 2020 年 11 月 11 日