Multilingual E-commerce API using Laravel 8.0 – Part 3 Product Controller

Now that we have created a middleware and can send the language code in the HTTP headers, let’s dive into our Product Controller where all the logic happens.

We will implement the following HTTP methods in the products endpoint.

  • Get
  • Post
  • Patch/Put
  • Delete

#Step 1

Let’s try to get a list of products from the database with English translation.

To do that let’s write a simple query using Laravel Eloquent ORM in the index() method.

   /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {   
        $locale = App::getLocale();

        $products = Product::with('translations')
                    ->whereHas('translations', function($query) {
                        $query->where('language_id', '=', 1);
                    })->get();

        return ProductCollection::collection($products);
    }

The $locale = App::getLocale(); code will get the language that we are setting in the checkLocale middleware

#Step 2

The next step is to store products with specific language in the database.

Our Store() or the Post Http method implementation looks something like this.

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(ProductRequest $request)
    {   
        $locale = App::getLocale();
        
        $productData = [
            'product_price' => $request->product_price,
            'category_id' => 1
        ];

        $productId = Product::create($productData)->id;

        //get Language id
        $language = Language::where('language_code', $locale)->first();

        $productTranslationData = [
            'product_name' => $request->product_name,
            'product_description' => $request->product_description,
            'product_id' => $productId,
            'language_id' => $language->id
        ];

        // Add data to the translation table
        $productTranslation = ProductTranslations::create($productTranslationData);

        // Send the data back as response
        $product = $this->getProductById($productId, $locale);

        return response(
            [
                'data' => new ProductResource($product)
            ], 
            Response::HTTP_CREATED
        );
    }

The $request object in the parameter is of type Product. We will change this this to parameter of type ProductRequest $request

As discussed in this article the ProductRequest object helps us in the validation of the input that we receive.

Since this is a single resource we pass the data through our ProductResource($product) class

#Step 3

We will implement the Update or the PATCH Http method.

The update() method takes in two parameters Request $request and Product $product

A few extra validations that we need to do when updating a product:

  • We need to check whether the product is already in the database
  • We need to check if there is a product with the same translation that we are trying to update.
  • Send appropriate error codes in the response if there are errors.
/**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\model\Product  $product
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Product $product)
    {   
        $locale = App::getLocale();

        // Check if a product exists with Translation
        $id = $product->id;
        $isProductInDb = $this->getProductById($id, $locale);

        if (is_null($isProductInDb)) {
            return response()->json(
				[
					'errors' => 'Resource not found!'
				],
				Response::HTTP_NOT_FOUND
			);
        }

        $oldProduct = Product::find($id);

        if (isset($request->product_price)) {
            $oldProduct->product_price = $request->product_price;
        }
        $oldProduct->category_id = 1;
        $oldProduct->save();

        //get Language id
        $language = Language::where('language_code', $locale)->first();

        $data = [];
        if (isset($request->product_name)) {
            $data['product_name'] = $request->product_name;
        }
        if (isset($request->product_description)) {
            $data['product_description'] = $request->product_description;
        }

        // Add product translation
        ProductTranslations::where('product_id', $oldProduct->id)
            ->where('language_id', $language->id)
            ->update($data);

        // Send the data back as response
        $product = $this->getProductById($oldProduct->id, $locale);

        return response(
            [
                'data' => new ProductResource($product)
            ], 
            Response::HTTP_CREATED
        );
    }

#Step 4

The last method that remains to be implemented is the delete Http method

/**
     * Remove the specified resource from storage.
     *
     * @param  \App\model\Product  $product
     * @return \Illuminate\Http\Response
     */
    public function destroy(Product $product)
    {
        $product->delete();
        return response(null, Response::HTTP_NO_CONTENT);
    }

Series Navigation<< Multilingual E-commerce API using Laravel 8.0 – Part 8 Product Request ObjectMultilingual E-commerce API using Laravel 8.0 – Part 4 Database Seeder and Factories >>