Let us consider a hypothetical scenario. Suppose we have five different tables in our database,
Our client wants us to add a search bar to the frontend, where a user can search for a specific product and upon tapping the search button, matching products has to be displayed on the frontend.
In order to add the aforementioned functionality, I came across the following strategy.
👉 I would add an input box to ender the product name and a submit button.
👉 Upon pressing the submit button, a GET request will be sent to the backend. On the query parameters, the product name that has been entered by the user will be included
👉 Once the GET request is received to the backend, I will pass it down to the ProductsController and from within a method defined inside the ProductController, I will use the Product model to query the products table to see if there are any matching results.
👉 If there are any matching results, I will send them to the frontend inside a JSON object and if there aren't any matching results, I will set a success flag to false inside the JSON object and send it to the frontend
👉 In the frontend, if there are any matching results, I will display them on the screen. Else, I will display "No Results Found!"
Everything works fine if we only want to search the products table. But what if, later our client tells us something like "Remember that search functionality you added for the products? I thought that functionality should be added to orders as well. I think as the list of orders by a user grows and grows, they should be able to search for their previous orders too."
👉 Now, since in our previous approach to search products was implemented in the ProductController using the Product model, when we are adding the same functionality to Orders, WE WOULD HAVE TO DO THE SAME THINGS WE DID IN THE ProductsController AGAIN INSIDE THE OrdersController USING THE Order model. It does not take seconds to understand that this leads to duplication of code.
❓ How do we add an API endpoint in laravel for a search functionality that can be used to search any table in our database and get results, instead of the search functionality being scoped to a specific controller and a corresponding model?
A good start would be to create a trait called something like searchable
and add it to all the models you want to search and put any shared logic between the different models in there. Possibly you'd want to manually allow different columns so in each model you have an array of searchable columns which you'd refer to in your trait.
Your controller would have to point to the related model and call a method in the trait that searches.
As others have pointed out this is a high level question so I won't go too much in detail. Of course there are a million ways to implement this, just try and keep shared logic in place.