Laravel RestAPI 구현하기 (3) - 상품조회,주문,주문조회 구현

 

Laravel RestAPI 구현하기 (3) - 상품조회,주문,주문조회 구현

  • 로그인,회원가입,로그아웃 구현 이후 상품조회,주문,주문조회 API를 구현합니다.
  • 상품등록은 Laravel RestAPI 구현하기(1)에서 대량등록한 상품으로 대체합니다.

 

routes/api.php에 API경로 추가하기

  • Laravel RestAPI 구현하기(2)에서 정의한 API경로에 상품,주문 관련 경로를 추가로 정의합니다.
Route::middleware('auth:api')->group(function () {
    Route::post('v1/logout',  [PassportAuthController::class, 'logout']);

    Route::resource('v1/orders', OrderController::class); // 주문관련
    Route::resource('v1/products',ProductController::class); // 상품관련
});

 

상품,주문 모델 정의하기

  • Laravel RestAPI 구현하기(1)에서 마이그레이션을 통해 products,orders table이 이미 생성되었기에 모델만 정의합니다.
  • App\Models\Order.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    use HasFactory;

    protected $fillable = ['user_email','product_id'];

    public function user()
    {
        // 여러 주문은 한명의 유저에게서 주문된다.
        return $this->belongsTo(User::class);
    }

    public function products()
    {
        // 한가지 주문으로 여러 상품을 시킬 수 있다.
        return $this->hasMany(Order::class);
    }
}
  • App\Models\Product.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;

    protected $fillable = ['name','price'];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function order()
    {
        // 한개의 상품은 여러 주문에서 쓰일 수 있다.
        return $this->belongsTo(Order::class);
    }
}

 

주문 관련 컨트롤러 생성 및 구현

  • 주문 관련 컨트롤러를 생성한다
// --resource option을 사용하여 RestFull한 액션에 대한 다양한 라우트 설정 가능.
$ php artisan make:OrderController --resource
  • 컨트롤러를 생성하였으면 API 요청에 해당하는 응답값을 리턴하는 기능들을 구현한다.
  • App/Http/Controllers/OrderController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Order;
use App\Models\Product;
use App\Models\User;

class OrderController extends Controller
{
    public function index()
    {
        // 주문 전체 조회
        // GET /api/v1/orders/
        $orders = auth()->user()->orders;
        if(!$orders) {
            return response()->json([ 'success' => false, 'message' => 'We can not found orders list. Plz check your orders'],401);
        }else{
            return response()->json([ 'success' => true, 'data' => $orders],200);
        }
    }

    public function show($id)
    {   
        // 주문 단건 조회
        // GET /api/v1/orders/{orderId}
        $orders = auth()->user()->orders()->find($id);
 
        if (!$orders) {
            return response()->json([
                'success' => false,
                'message' => 'Post not found '
            ], 401);
        }
 
        return response()->json([
            'success' => true,
            'data' => $orders->toArray()
        ], 200);
    }
 
    public function store(Request $request)
    {
        // 주문요청
        // POST /api/v1/orders/
        $userId = auth()->user()->token()->user_id;
        if(!$userId) 
            return response()->json([ 'success' => false, 'message' => 'This Token Not Availabled'], 401);

        $user = User::where('id',$userId)->first();
        $this->validate($request, [
            'product_id' => 'required',
        ]);

        $product = Product::where('id',$request->product_id)->first();
        if(!$product)
            return response()->json([ 'success' => false, 'message' => 'This Prudoct Id Not Availabled'], 401);
 
        $orders = new Order();
        $orders->user_email = $user->email;
        $orders->product_id = $request->product_id;
 
        if (auth()->user()->orders()->save($orders))
            return response()->json([
                'success' => true,
                'data' => $orders->toArray()
            ]);
        else
            return response()->json([
                'success' => false,
                'message' => 'orders not added'
            ], 500);
    }
 
    public function update(Request $request, $id)
    {
        // 주문 수정
        // PUT /api/v1/posts/{orderId}
        $orders = auth()->user()->orders()->find($id);
 
        if (!$orders) return response()->json(['success' => false,'message' => 'orders not found'], 401);
 
        $updated = $orders->fill($request->all())->save();
 
        if ($updated) 
            return response()->json([ 'success' => true]);
        else
            return response()->json([ 'success' => false,'message' => 'Updated Faild.'], 500);
    }
 
    public function destroy($id)
    {
        // 주문 삭제
        // DELETE /api/posts/{orderId}
        $orders = auth()->user()->orders()->find($id);
 
        if (!$orders) return response()->json(['success' => false,'message' => 'orders not found'], 401);
 
        if ($orders->delete()) 
            return response()->json(['success' => true]);
        else 
            return response()->json(['success' => false,'message' => 'Post can not be deleted'], 500);
        
    }

}

 

상품 관련 컨트롤러 생성 및 구현

  • 상품 관련 컨트롤러를 생성한다.
// --resource option을 사용하여 RestFull한 액션에 대한 다양한 라우트 설정 가능.
$ php artisan make:ProductController --resource
  • 컨트롤러를 생성하였으면 API 요청에 해당하는 응답값을 리턴하는 기능들을 구현한다.
  • App/Http/Controllers/ProductController.php
<?php

namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        // 주문 전체 조회
        // GET /api/v1/products/
        $product = Product::all();
        if(!$product) {
            return response()->json([ 'success' => false, 'message' => 'We can not found Products list.'],401);
        }else{
            return response()->json([ 'success' => true, 'data' => $product],200);
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Product  $product
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        // 상품 단건 조회
        // GET /api/v1/products/{productId}
        $product = Product::where('id',$id)->first();
        if(!$product) {
            return response()->json([ 'success' => false, 'message' => 'We can not found Products list.'],401);
        }else{
            return response()->json([ 'success' => true, 'data' => $product],200);
        }
    }
}

 

상품 주문 테스트

  • 테스트는 Laravel RestAPI 구현(2) 에서 진행한 Postman으로 진행합니다.
  • Headers에 accept를 application/json 형식으로 지정합니다.
  • 로그인 테스트에서 얻은 token값을 복사하여 Authorization의 Bearer Token값으로 넣어줍니다
  • 상품 주문에 필요한 필수 값(product_id)를 form-data에 넣어 준 후 send를 보냅니다.
  • 응답 데이터를 확인합니다.

 

주문 조회 테스트

  • 테스트는 Laravel RestAPI 구현(2) 에서 진행한 Postman으로 진행합니다.
  • Headers에 accept를 application/json 형식으로 지정합니다.
  • 로그인 테스트에서 얻은 token값을 복사하여 Authorization의 Bearer Token값으로 넣어줍니다
  • resouce옵션으로 제작한 컨트롤러의 index와 show는 GET방식입니다.
  • 응답 데이터를 확인합니다.

 

 

상품 조회 테스트

  • 테스트는 Laravel RestAPI 구현(2) 에서 진행한 Postman으로 진행합니다.
  • Headers에 accept를 application/json 형식으로 지정합니다.
  • 로그인 테스트에서 얻은 token값을 복사하여 Authorization의 Bearer Token값으로 넣어줍니다
  • resouce옵션으로 제작한 컨트롤러의 index와 show는 GET방식입니다.
  • 응답 데이터를 확인합니다.

 

단건 조회 테스트

  • 상품 , 주문 단건 조회의 경우 show($id)를 통해 진행됩니다. ex) /api/v1/orders/2
  • 테스트는 Laravel RestAPI 구현(2) 에서 진행한 Postman으로 진행합니다.
  • Headers에 accept를 application/json 형식으로 지정합니다.
  • 로그인 테스트에서 얻은 token값을 복사하여 Authorization의 Bearer Token값으로 넣어줍니다
  • resouce옵션으로 제작한 컨트롤러의 index와 show는 GET방식입니다.
  • 응답 데이터를 확인합니다.

 

마무리

  • resource controller와 routes resource를 활용하면 액션을 쉽게 활용 할 수 있습니다.

 

관련글