Fast API Endpoints with Laravel & OOP – by Nathan King

API’s aren’t something new in the industry, but they’re vital in a lot of cases. Having your application completely separate from it’s data has many benefits; not least a separation of concerns and the ability to plug in multiple apps to the same datastore. My preferred framework for building RESTful API’s is Laravel, and I have a few tricks up my sleeve enabling me to construct new API endpoints within minutes once the boilerplate is set up. This tutorial is going to take you through setting up that boilerplate so you too can amaze your non-technical bosses with the speed you can work!


This tutorial assumes you already have a development environment set up ( I recommend Laravel's own Homestead link: https://laravel.com/docs/5.2/homestead ) and a base Laravel project ready to start developing in.

The data

Laravel already comes with a User model & migration right out of the box, so let's use that. You'll be able to use all of the same steps in this guide for your own models, but creating migrations & models is out of scope for this guide


Let's create a simple route for retrieving all users and a user by ID in our app/Http/Routes.php

Digital Recruitment - Ronald James Group

First, we wrap our routes in a group with a prefix of 'api'. This will ensure that the URL's used for our API will look something like http://localhost/api/users.

Next, we've supplied two API endpoints (users and users/{id}). They both use the same controller, and they both use the same method on that controller. When calling these endpoints, you'll be writing something like http://localhost/api/users/1 to select a user with an ID of 1.

2 - Controllers

Controllers should only contain code to handle the request and serve a response, you should never put logic or data code in a controller. What we'll be doing is creating Controllers and Services; the service classes will handle the logic & data interaction for the controller.

All of your controllers will largely contain the same methods and perform the same actions. What does that tell us? We can abstract that functionality away and into a base class!

Let's create a class called BaseController in the app/Http/Controllers directory...

Digital Recruitment - Ronald James Group

Let's walk through the code.
Our class extends Laravel's own Controller class (because every Controller needs to extend that class, we have our own BaseController extend it. Every controller we create will extend our BaseController rather than Laravel's Controller).

The class contains a protected $service member. What's that for? Well, that's going to contain a service class instance that we're going to create soon.

For the classes constructor method, we're using Laravel's IoC to dependency inject a class called Service (which we'll be creating soon, remember!) and assign $this-& service to an instance of it. The class will be located in app/Services, so the namespace for the class is App\Services.

Finally, we have a get method that contains an optional $id parameter. The method returns a JSON response object by calling the service's get method, passing in the ID supplied (if any). In actuality, the class named Service is abstract so it won't be used directly - but since we know that every service we create will contain the same methods, we can use them in our BaseController. Hey, isn't that polymorphism?

3 - Services

Now that we have our routes and our BaseController, let's go ahead and create our abstract Service class in app/Services...

Digital Recruitment - Ronald James Group

Let's walk through the code for our class.

First, we've marked the class as abstract - this means the class can't be instantiated or used directly, we have to extend it.

We have a protected $model member, which is going to hold an instance of the Model our service is working with. We'll look into that more soon.

Within our constructor, we're assigning $this->& model to the return value of an abstract function in our class named model(). This is the only function we'll need to override when we extend our Service class. When we override it, we'll simply be returning an instance of the model we want our service to work with.

Finally, our get method – this is what our controller was calling within its own get method. We're checking whether $id is null and if it is, we're returning all results of our model. If it's not null, we're finding the result of our model by a specific ID. Simple, right?

4 - Creating the User Service

Now that we have our abstract service, let's create an actual service that can be used in our controllers. Create a new class named UserService in app/Services...

Digital Recruitment - Ronald James Group

Wow, that's small and maintainable, huh?

We're extending our abstract Service class which contains our ready-made functionality for retrieving records. All we've done is implement the model() function, having it return a new instance of our User model. That's all! Now our service knows which model to work with, we don't need to do anything else.

5 - Creating the User Controller

Now that we have a service, we can create the controller that our routes are using. Let's create a class named UsersController in app/Http/Controllers...

Digital Recruitment - Ronald James Group

Wow, is that it? Yes!

We're extending our own BaseController class that we created earlier – that's the one that contains our functionality for interacting with our service classes.

The only method we need to implement is the __construct method. Using Laravel's IoC, we're injecting our specific UserService into the method, and passing that directly into our parent classes constructor That's it, we have two fully functional API endpoints for our user's data!

6 - Wrapping Up

Now that you have a BaseController and an abstract Service, you'll be able to create entirely new API endpoints in a matter of minutes. Of course, sometimes you'll need to perform some extra logic in your service – when that's the case, you can easily override methods when required.

Obviously, more has to go into all of this to make it a production-ready API. Ideally, you'll need to include POST, PUT and DELETE methods as well as some authentication middleware. Once you've created a few more GET endpoints, why don't you have a go at those other methods?

Thanks to Nathan King of Crudle ( link: http://www.crudle.co.uk/ ) for being our guest writer this week.

Who Are Ronald James?

We are a leading niche digital & tech recruitment specialist for the North East of England. We Specialise in the acquisition of high-performing technology talent across a variety of IT sectors including Digital & Technology Software Development.

Our ultimate goal is to make a positive impact on every client and candidate we serve - from the initial call and introduction, right up to the final delivery, we want our clients and candidates to feel they have had a beneficial and productive experience.

Contact our Team

If you’re looking to start your journey in sourcing talent or find your dream job, you’ll need a passionate, motivated team of experts to guide you. Check out our Jobs page for open vacancies. If interested, contact us or call 0191 620 0123 for a quick chat with our team.

Let's be Friends!

Follow us on our blog, Facebook, LinkedIn, Twitter or Instagram to follow industry news, events, success stories and new blogs releases.


Back to Blog

</Follow Us>