iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0
Software Development

Laravel 後端菜鳥可以知道的流程概念系列 第 15

後端菜鳥需要會通靈?前後端分離與不分離的資料傳遞

  • 分享至 

  • xImage
  •  

後端菜鳥(我自己)在專案開發上常常需要通靈(?)

專案的開始很可能只有線稿圖,或甚至什麼都沒有。對於菜鳥開發者來說就會變得有點需要想像力,去規劃傳入及傳出的資料。

因此今天來分享我在 GroupController 及 ProductController 的 create 及 store 功能,以及這個流程下,後端需要收到、處理後回覆的資料。

程式碼撰寫

當使用者想要 新增一個團購,網站會先回傳一個空白表單的頁面,使用者填寫完畢後送出,網站需要檢查使用者輸入的每個欄位,確定沒問題再寫進資料庫。

https://ithelp.ithome.com.tw/upload/images/20230930/20162893zIMxXkrCUu.png

Routes

// 團購本身相關 route
Route::resource('/group', GroupController::class)
    ->only(['create', 'store']);

// 團購內產品相關 route
Route::prefix('/group/{group}')->group(function () {
   Route::get('/product/create', [ProductController::class, 'create']);
		// ...先保留,還要放其他 route
});

Controller (前後端不分離)

public function create()
{
	// 因為還沒寫會員功能,先用 hardcode 寫入發起人
    $organizer = [
        'id'   => 1,
        'name' => 'Mia'
    ];

	// 給予使用者空白表單
    return view('group.createGroup', [
        'organizer' => $organizer,
    ]);
}

public function store(Request $request)
{
    // 表單欄位驗證
    $validated = $request->validate([
        'group_name'           => 'required|string|min:3|max:50',
        'organizer_id'         => 'required|int',
        'close_price'          => 'nullable|decimal:0,2',
        'close_date'           => 'nullable|date|after_or_equal:today',
        'allow_insert_product' => 'nullable',
        'status'               => 'required|int',
    ]);

	// 需求設定是兩個欄位一定要有一個有
    abort_if(
        !$validated['close_date'] && !$validated['close_price'],
        Response::HTTP_BAD_REQUEST,
        __('請設定團購截止條件')
    );

    $group = Group::create($validated);

	// 我的需求:團購新增後,直接跳轉到下一個畫面,給使用者新增產品
    return redirect(url("/group/$group->id/product/create"));
}

View

來看一下我的小成果!

  1. 首先點選「開團囉」會出現此空白頁面讓使用者新增

    public function create()
    {
    	// 因為還沒寫會員功能,先用 hardcode 寫入發起人
        $organizer = [
            'id'   => 1,
            'name' => 'Mia'
        ];
    
    	// 給予使用者空白表單
        return view('group.createGroup', [
            'organizer' => $organizer,       
            // 帶入發起人 id,被我藏在 html 表單的隱藏欄位
        ]);
    }
    

    https://ithelp.ithome.com.tw/upload/images/20230930/201628937NKF28fyrD.png

    使用者填寫完畢,點選「下一步:新增商品」時,瀏覽器會將表單資料發到 controller

    // GroupController
    public function store(Request $request)
    {
        dd($request->input());
        // 可以看到前一個畫面傳入什麼資料
    }
    

    https://ithelp.ithome.com.tw/upload/images/20230930/20162893VtSvFGT5u4.png

  2. 新增完後點選「下一步:新增商品」,將團購的資料帶入 GroupController 的 store 功能,經過一些程式碼驗證後,新增此筆資料儲存到 groups table 中

    // GroupController
    public function store(Request $request)
    {
        // 表單欄位驗證
        $validated = $request->validate([
            'group_name'           => 'required|string|min:3|max:50',
            'organizer_id'         => 'required|int',
            'close_price'          => 'nullable|decimal:0,2',
            'close_date'           => 'nullable|date|after_or_equal:today',
            'allow_insert_product' => 'nullable',
            'status'               => 'required|int',
        ]);
    
    	// 需求設定是,兩個欄位一定要有一個有
        abort_if(
            !$validated['close_date'] && !$validated['close_price'],
            Response::HTTP_BAD_REQUEST,
            __('請設定團購截止條件')
        );
    
        $group = Group::create($validated);  // 新增進資料庫
    
    	// 我的需求:團購新增後,直接跳轉到下一個畫面,給使用者新增產品
        return redirect(url("/group/$group->id/product/create"));
    }
    
  3. 團購資料新增完成後,我想要讓使用者直接進行下一步新增團購內的產品資料,因此直接轉址到 ProductController 的 create 功能,顯示產品新增的空白表單

    // ProductController
    public function create(Group $group)
    {
        return view('group.createProduct', [
            'group' => $group,                  // 把團購資料帶進去畫面 
        ]);
    }
    

    https://ithelp.ithome.com.tw/upload/images/20230930/20162893tH2bepWttY.png

    // ProductController
    public function store(Request $request)
    {
        dd($request->input());
    	// 一樣用 dd() 查看送出了什麼資料到 controller
    }
    

    https://ithelp.ithome.com.tw/upload/images/20230930/20162893IkUwgQU11l.png

  4. 使用者新增完產品後,再跳轉到 顯示團購資料 的畫面,讓使用者可以先登記跟團加購

    // ProductController
    public function store(Request $request)
    {
        $validated = $request->validate([
            'group_id'            => 'required|int',
            'data'                => 'required|array',
            'data.*.product_name' => 'nullable|string|max:255',
            'data.*.price'        => 'nullable|required_with:data.*.product_name|int'
        ]);
    
        $productsData = array_filter($validated['data'], function ($data) {
            return isset($data['product_name']);
        });
    
        $group = Group::find($validated['group_id']);
        $group->products()->createMany($productsData);
    
        return view('group.showGroup', [
            'group'    => $group,
            'products' => $group->products,
        ]);
    }
    

    https://ithelp.ithome.com.tw/upload/images/20230930/201628937gpYYNHYJC.png

如果是前後端分離?

從上面我們容易接觸到的流程,可以想一下後端需要收到什麼、傳出什麼

https://ithelp.ithome.com.tw/upload/images/20230930/201628933DBhq7ZumK.png

上面前後端不分離的流程中

  1. 回傳空白表單讓使用者新增 團購資料 及

  2. 回傳空白表單讓使用者新增 產品資料

這兩項工作都是前端直接渲染處理

後端需要處理:

  1. 新增所填寫的團購資料 及

  2. 新增所填寫的產品資料

新增所填寫的團購資料

原本前端傳入:

https://ithelp.ithome.com.tw/upload/images/20230930/20162893yDM9ooDU9G.png

如果用 postman 打:(後端的傳入傳出)

https://ithelp.ithome.com.tw/upload/images/20230930/20162893IxPpnfUsnm.png

新增所填寫的產品資料

原本前端傳入:

https://ithelp.ithome.com.tw/upload/images/20230930/20162893cb2bdQ2i8r.png

如果用 postman 打:(後端的傳入傳出)

傳入多筆資料可以選擇 JSON 格式
https://ithelp.ithome.com.tw/upload/images/20230930/20162893S5LrXZl3hN.png

回傳的資料包括團購資料 、以及產品資料
https://ithelp.ithome.com.tw/upload/images/20230930/201628931YiiSc0B19.png

小結

分享這些畫面純粹是因為開發時常常碰到不知道該處理什麼資料、回傳什麼資料的情況,希望藉由這個小分享提供大家一些想法。(預計在後兩天說明這篇所用的部分程式碼說明與相關的 Laravel 功能)

不過也在此說明,上面都只是我個人的做法,實際上專案應該依照不同需求、團隊溝通的方式去開發,包括前端該給什麼資料、後端該回傳什麼資料、以及資料的格式,都是需要前後端溝通討論的。


上一篇
專案筆記:Controller index, show, destroy 功能、paginate分頁
下一篇
Laravel 資料驗證:Validation
系列文
Laravel 後端菜鳥可以知道的流程概念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言