Featured resource
pluralsight tech forecast
2025 Tech Forecast

Which technologies will dominate in 2025? And what skills do you need to keep up?

Check it out
Hamburger Icon
  • Labs icon Lab
  • Core Tech
Labs

Guided: Building an e-commerce Platform in Laravel - Part 1

This lab will guide you in creating a sophisticated e-commerce platform. Learn to integrate Breeze authentication, perform CRUD operations on products, and manage user roles and permissions with Laravel’s features. In this first part of a two-lab series, you’ll set up the basic Product model and enable authorized users to manage products through a web interface. From setting up your project to implementing product listing and management interfaces, this lab provides all you need to build secure and maintainable e-commerce applications.

Labs

Path Info

Level
Clock icon Intermediate
Duration
Clock icon 1h 19m
Published
Clock icon Jun 10, 2024

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Introduction

    In this Guided Code Lab, you will learn how to create a simple e-commerce prototype type application and protect it with authentication and authorization. Authentication will be implemented with the Laravel Breeze package. This lab is the first part, there will also be a second lab that will continue on what you build here.

    Each task can be validated individually by clicking on the Validate button next to it.

    If you are stuck, you can always check out the details section of the task or the solutions directory. The task will give you feedback if you don't complete it correctly. A failed task will have one or more failed tests under the Checks section of the task. You can check out the output of these failed tests to see what went wrong. The solutions folder at the top of the workspace contains the final state of the application after finishing the lab.

    The starting point of the lab is a Laravel application named "shop". The current directory of the built-in Terminal will be set to the shop/ directory.

    You can use the Terminal to run the development server with the Artisan CLI or to run other Artisan commands. The Run button will automatically start the Artisan development server.

    There is also a web browser that you can use to access the development server endpoints and see the app. So when you get to the point where you need to run the server, you can open this {{localhost:8000}} link and see the running dev server.

    The templates that you'll need are already prepared for this lab and placed inside of the views/ directory. The application will use the MySQL server that is already running in the background. Other than these changes, the "shop" project is basically a brand new application created with the "laravel" installer. The Laravel Breeze "Blade with Alpine" starter kit is also used, which you will need for authentication.

    The changes made to the new project are minimal, but if you want to know exactly which changes are made before starting the lab, you can check it out below:

    See the changes

    This application is created with the "laravel new" command. Depending on the version of the installer you use, you might see different options. This lab uses the "Laravel Breeze" starter kit with the "Blade with Alpine" option. This is because you don't need anything complex for the front-end and Alpine.js will do just fine. But Breeze package can also be installed after you created a new Laravel app. You need to find the latest documentation on how to install it and how to publish it's assets. You will notice that there are already some controllers and views present in the application, this is what you get out of the box with Breeze.


    The MySQL server is running in the background and the database connection is already configured inside of the `.env` file. Also, the "shop" database is already created, but it's empty.


    The assets (TailwindCSS and Alpine.js) are already built, so you don't need to worry about them, as this lab will not focus on templates and styling.


    Other than these changes, there are also templates that you'll need for this lab. These templates include the main layout template and all of the other product and user templates. The default "welcome" template and route are removed and replaced with the "home" page.


    Also the default Breeze redirections after the login and registration from "dashboard" route are also changed to the "home" route. You can do this by changing the `HOME` constant from the RouteServiceProvider.

    Click on the next step to get started!

  2. Challenge

    Implementing the Product Resource

    The center of every e-commerce site is a product. So you first need to create a Product model to store products in the database. Now that you have the Product model ready, you need to edit the migration file and add all of the columns for the new products table. Storing new products in the database will be easier if you can mass assign values from the user's input. But to do that, you will first need to specify which attributes are allowed to be mass-assigned, in other words, which values are "fillable". The database is ready to store products. Now it's time to implement some business logic that will allow you to implement all of the product's CRUD (Create, Read, Update, Delete) operations. You need to create the ProductController. Before actually implementing all of the controller's actions, you need to define all of the resource routes and connect them to the appropriate actions. Instead of defining each route separately, you can follow the convention and simply use the resource method of the Route facade. You should also use the middleware method with the 'auth' middleware to restrict the access to these routes to only authenticated users.

    The 'home' route is the only custom route in there for now, other routes that you see there are all created by Laravel Breeze and you can leave them as they are. The resource method will connect endpoints to their corresponding actions from the resource controller.

    The table below represents the relationship between the created routes and actions:

    | Verb | URI | Action | |-----------|--------------------------|---------| | GET | /products | index | | GET | /products/create | create | | POST | /products | store | | GET | /products/{product} | show | | GET | /products/{product}/edit | edit | | PUT/PATCH | /products/{product} | update | | DELETE | /products/{product} | destroy |

  3. Challenge

    Creating and Showing Products

    The product resource controller has two actions, which you should use for storing new products in the database: create and store. The create action should return a form for submitting a new product. That form should send the user's input to the store action, which will use the Product model to store a new product in the database.

    To save on time and avoid typing out a bunch of HTML, all of the templates are already prepared. This will allow you to focus on the business logic of the application. However, feel free to check out these templates, to see how Blade directives are utilized. The create action should just render the create.blade.php template, which you can find inside of the resources/views/products directory.

    As you can see, the template is extending the main layout template from the layouts directory. But don't worry about that now, just focus on the content section. The single form sub-template is used to create both forms for creating new and updating existing products.

    The form sub-template is in the same directory. You can see that this is a simple form with all of the attributes you defined for the Product model. The form action and method attributes will be slightly adjusted based on which form is supposed to be rendered. In this case, the form action will send data to route('products.store') and the method will be POST.

    So once the form is submitted, the store action will receive the user's input. The store action will store a new product in the database and redirect the user to the show page of the new product. To make this happen, you need to render the show.blade.php template from the show action.

    The template itself is not complex, it just outputs all of the details about the product from the {product} route parameter. It also includes a link to the edit page and a button for removing the product, but you will implement these in the next step. The show action is focused on one single product. The index action is usually used to present all products from the database. In production, this usually means a specific number of products with pagination.

    You should provide all of the products from the database to the index.blade.php template. This template will present them in the form of cards and the name of each product will lead the user to the show page of that specific product. Finally, you can start the development server in the Terminal, by running the php artisan serve command or by clicking on the Run button. Use the Web Browser to see what the application looks like.

    As you can see, the application already has a navigation menu bar. This navigation is a part of the layout.blade.php template from the layouts directory and each template from the lab extends this main layout.

    The login and register routes are pointing to the actions from the Laravel Breeze package, so you get this authentication out-of-the-box. The menu will look different for authenticated users, which is implemented with the help of @guest and @auth Blade directives. Try to start up the server and register with some random data. After that, you can login and you will see that you are able to click on Create Product link which will lead the user to the create action you implemented.

    From there, you can try to create new products and see how they look on the show page and the index/home page.

  4. Challenge

    Updating and Deleting Products

    So now you have the workflow for creating and showing new products on the page. You also have the authentication ready because of Laravel Breeze and all of the product-oriented routes are protected by it, so that only registered users are able to create new products.

    If you check out the show template, you will see that there is a link which points to the edit action. This should allow users to update existing products. Next, you will implement the action in the controller. Just like the create action, the edit action is just there to provide the user with the web form. The edit.blade.php template makes use of the same form from the form.blade.php partial, but this time, the action is pointing to the update route and the HTTP verb is set with the @method('PUT') directive. Also, the old values of the product attributes are shown with the help of the old() helper function. You can try to click on the Edit button now on the product's show page. This should allow you to update the details of the existing product.

    To finish implementing all of the CRUD operations, you should also implement the destroy action for deleting products. The Delete button on the show page should use the destroy action to remove the product from the database. It is implemented by creating a simple form that only has the submit button and once you click on it, the id of the product will be sent to the destroy action with the @method('DELETE') HTTP verb.

  5. Challenge

    Connecting Users with Products

    You might've noticed that the product's show page contains the "Posted by: No one" string. Even though only registered users can submit new products, the information about which specific user submitted the product is not stored anywhere.

    However, when you want to buy a product, it is important to know who the seller is and who is responsible for managing information about that specific product. That's why you need to create a relationship between the users and products. The User model is already created and utilized by Laravel Breeze, all you need to do is create a "has-many" relationship with the Product. The foreign key inside of the products table will remember the user's id. The relationship is established on the database level. To utilize the full potential of this relationship with Eloquent models, you need to define relationship methods in both the User and Product classes. The relationship is now established, but the user's id is still not stored in the user_id column. To do that automatically, you can make use of the products() relationship method, inside of the store action of the ProductController. You can check the database to see if the user's id is stored with every new product. However, it would be much more convenient to see that on the product's show page. You can test if everything works by registering as a new user and submitting a new product. The "Posted by:" string in the show page should now include the name of the user.

  6. Challenge

    Developing the Seller Page

    Users can now submit new products to sell them on the site. In that context, users are sellers. When you are trying to buy a product, you would usually want to know who you're buying it from. This info should be accessible on the seller's page. Next, you will create it. The seller's page should now show some of the user's info and all of the products they posted, however, the only way to access this page is to type in the path directly into the address bar. You should make this more accessible. The Profile link inside of the Account dropdown should point the users to their own "seller" page. In production, you would probably add some additional links for editing account information with the help from Breeze. In this app, the Profile link should simply redirect the user to the "seller" page with it's own id. The seller page is now completely integrated into your e-commerce application!

  7. Challenge

    Implementing Authorization

    Only authenticated users are allowed to manage products. However, you might've noticed that every user is allowed to edit or delete any one of the products. This is not a preferred behavior. Only the seller of the product should be allowed to make modifications of that specific product. This is why you need to implement authorization.

    You can create a ProductPolicy which will specify the rules on who can update or delete particular products. Now that the policy is ready, you can use it to restrict the access to the modification actions, like the edit, update, and destroy actions of the ProductController. Only the users who are authorized to make modifications on the product should be allowed to proceed. The updating and deleting of products is now allowed only for the owners of that specific product. Unauthorized users will not be able to access these endpoints. However, there is something that you should change to improve your app from the perspective of the user experience (UX).

    If a user is not authorized to modify a specific product, then that user should not be able to see the Edit and Delete buttons on the product's show page. You can use the built-in Blade directives to only show these buttons to authorized sellers. And that's it for the part one! Congratulations, you just built a simple e-commerce site that supports all of the product's CRUD operations, together with the authentication and authorization. Authenticated users can post new products and edit them. The second part of this lab will be available soon.

    If you closed down the browser, here is the link where you can see what you made: {{localhost:8000}}

    In the next part, you will go over implementing product categories and you will allow users to actually make orders so that someone can buy the products. However, up to this point, there are some things that you could do to improve this application on your own. Here are some suggestions:

    • Some type of pagination would be useful on the product's index page as well as any other page that shows a list of products (like the seller page).
    • The home page could have a search bar, which would allow users to filter through products by name.
    • The product's show page could include a reviews/comments section which would allow user's to inform others about the quality of the given product.
    • All of the routes that need to work with a specific product include an id of the specific product in the path. It would be more user friendly (and more secure) to implement some type of a slug.

Mateo is currently a full stack web developer working for a company that has clients from Europe and North America. His niche in programming was mostly web oriented, while freelancing, working on small startups and companies that require his services. Go(lang), Elixir, Ruby and C are his favorite languages and also the ones he’s mostly working with other then PHP in day to day work. He has a big passion for learning and teaching what he knows the best. His big interests recently have been the fields of DevOps, Linux, functional programming and machine learning.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.