Laravel API Course

1. Intro & Setup

Welcome to the Laravel API course! Get ready to dive into the exciting world of building APIs with Laravel, the powerful and flexible PHP framework.

15:57

2. Cleaning up Laravel

Ready to supercharge your Laravel project for an API-first approach? Let’s dive into optimizing and cleaning it up to make it lightning-fast and ultra-efficient!

16:19

3. Data Modeling

When building an API, mastering the art of structuring your data and defining dynamic relationships between various entities is absolutely essential in Laravel 11.

24:27

4. API Design

When you design an API, it’s absolutely crucial to understand that every API should have a meaningful purpose!

33:09

5. Authentication & Authorization

Say goodbye to the hassle of manually crafting every single detail, and say hello to a streamlined, efficient process that keeps your endpoints vividly documented and ready to go!

14:15

6. Rate Limiting

When it comes to managing API requests, rate limiting is a key player. You don’t want to open the floodgates and let users bombard your API with endless requests.

8:24

7. API Versioning

API versioning might sound like a minor detail at first, but trust me, it's one of those decisions that can make or break the future usability of your API.

22:22

8. Pagination

When you're handling requests that could return extensive lists of resources, it's essential to implement pagination to ensure your responses are manageable and user-friendly.

11:43

9. API Standards

API standards, while useful, aren’t the be-all and end-all. What often takes precedence is discoverability and consistency in your API design.

26:17

10. Handling Errors

Today, we'll explore how to leverage Laravel 11’s error handling system by implementing the API Problem Specification and enhancing it with custom packages to provide consistent, informative error responses.

26:49

11. Write Operations

Let’s explore the steps to manage resources in a Laravel 11 API, focusing on creating, validating, updating, and deleting resources. We’ll use a real-world approach to ensure clarity and usability.

29:30

12. Internationalization

In our previous video, we dove deep into handling write operations—everything from data validation and authorization to deciding between synchronous and asynchronous processing.

11:44

13. Caching Data

In our previous video, we dove deep into handling write operations—everything from data validation and authorization to deciding between synchronous and asynchronous processing.

18:08

14. Basic Security

When it comes to API security, think of it not as a threat but as an opportunity—a chance to build robust, multilayered defenses around your API.

9:53

15. Cache Requests

In Laravel 11, we can take advantage of built-in HTTP features to manage our cache more effectively, streamlining both the response time and the overall user experience.

8:40

16. Scheduling tasks & Sending requests

When working on a Laravel API, the task scheduling system plays a significant role in automating background jobs.

40:33

17. Notifications

Whether you're building a ping service or any application that requires user communication, you’ll likely need to notify users when certain actions occur, such as a service failure.

15:57

18. Monitoring and Logging

When you're developing APIs, it's important to have a clear picture of how your API is performing in real-time.

21:33

19. Testing

When you're developing APIs or any web-based product using Laravel 11, testing plays a crucial role in ensuring that your application behaves as expected.

18:01

20. API Platform

When it comes to building web applications, Laravel has long been a go-to framework for many developers. It's a robust framework, especially for full-stack applications.

17:16

21. Feature Flags

When it comes to building web applications, Laravel has long been a go-to framework for many developers. It's a robust framework, especially for full-stack applications.

11:05

22. Web Sockets

When you're working with APIs, there's a common misconception that WebSockets aren't relevant.

9:58

23. Search API

When you're building APIs, one key feature that often gets overlooked is search. That's what we’ll explore today using TypeSense(https://typesense.org/), a powerful open-source search engine.

15:30

24. Documenting your API

By default, API Platform will give you an OpenAPI specification (currently version 3.1). This standard format allows your API to be easily understood by machines and developers alike.

07:06

Want an easy-to-use API Observability Tool? Try Treblle now

Testing

About this lesson

When you're developing APIs or any web-based product using Laravel 11, testing plays a crucial role in ensuring that your application behaves as expected.

18:01 October 4, 2024

When you're developing APIs or any web-based product using Laravel 11, testing plays a crucial role in ensuring that your application behaves as expected. Whether you're using PHPUnit, Pest PHP, or any other testing framework like Codeception, the goal remains the same: building confidence that your application performs reliably under all circumstances.

In this guide, we’ll break down some key aspects of testing APIs in Laravel 11 using the Pest PHP testing framework. Don’t worry if you prefer PHPUnit—most of the testing principles we discuss will apply regardless of the framework.

Why Testing Matters

Before diving into the code, let’s quickly cover why testing is essential. Testing isn't just about catching bugs—it’s about guaranteeing that each part of your API functions correctly and continues to work as intended when other parts of the system are modified.

Getting Started with Testing Your Laravel API

When working with APIs, the first thing you might want to test is how different types of users interact with your endpoints. For instance, let’s start by checking the status codes returned for authenticated and unauthenticated users.

#[Test]
public function unauthenticated_user_gets_correct_status_code(): void
{
    $this->getJson('/api/services')->assertStatus(HttpResponse::HTTP_UNAUTHORIZED);
}

Here, we’re testing that an unauthenticated user attempting to access the services route gets an HTTP 401 Unauthorized status code. This is a simple yet important test to ensure security measures are in place.

Testing for Authenticated Users

Next up, you’ll want to verify that authenticated users get the expected status code and data they are authorized to see.

#[Test]
public function authenticated_user_gets_correct_status_code(): void
{
    $this->actingAs(
        User::factory()->create(),
    )->getJson('/api/services')->assertStatus(HttpResponse::HTTP_OK);
}

Here, we authenticate the user using Laravel's actingAs() helper, run the same request, and expect an HTTP_OK status (200).

Simplifying with Fluent JSON Testing in Laravel 11

When testing your API, you’ll often need to check that the data returned by the API matches the expected format. Laravel’s Fluent JSON Testing makes this easy by allowing you to assert various parts of the JSON response.

For example, say you want to ensure that users only see resources they own.

#[Test]
public function user_sees_only_their_own_resources(): void
{
    $user = User::factory()->create();
    $otherUser = User::factory()->create();

    Service::factory()->count(2)->for($user)->create();
    Service::factory()->count(10)->for($otherUser)->create();

    $this->actingAs($user)->getJson('/api/services')->assertJsonCount(2, 'data');
}

In this test, the user should only see the two services they own, even though there are a total of twelve services in the database.

Structuring API Responses: Ensuring Compliance

Another crucial part of API development is ensuring that responses follow the correct structure, especially when working with standards like JSON.

Testing your response structure helps maintain consistency and meets API design expectations.

#[Test]
public function response_comes_in_standard_format(): void
{
    $user = User::factory()->create();
    Service::factory()->count(2)->for($user)->create();

    $response = $this->actingAs($user)->getJson('/api/services');

    $response->assertJsonStructure([
        'data' => [
            '*' => [
                'id',
                'type',
                'attributes' => [
                    'name',
                    'url',
                    'created_at'
                ],
                'links'
            ]
        ]
    ]);
}

This ensures that the API response includes the necessary keys like id, type, attributes, and links, adhering to the expected API response format.

Pagination: Ensuring Correct Data Flow

Most APIs implement some form of pagination to prevent overloading clients with data. Testing pagination ensures the API delivers the correct amount of data per page.

#[Test]
public function pagination_works_correctly(): void
{
    $user = User::factory()->create();
    Service::factory()->count(15)->for($user)->create();

    $this->actingAs($user)->getJson('/api/services')->assertJsonStructure([
        'data',
        'links',
        'meta'
    ])->assertJsonCount(10, 'data'); // assuming pagination is set to 10 items per page
}

By testing pagination, you ensure that your API delivers the correct number of records on each page and includes necessary metadata like links and meta for the pagination controls.

Debugging Tests: What to Do When Tests Fail

Even the best-written tests fail from time to time. When they do, it’s important to know how to debug them. One simple method is using Laravel's dump() and dd() functions to inspect the data:

dd($response->json());

This allows you to see the exact output of your API and diagnose what might be causing the test to fail.

Conclusion

Testing is a fundamental part of building reliable Laravel APIs. By ensuring that unauthenticated users receive the correct status codes, authenticated users access the correct data, and API responses follow the required structure, you can build robust, scalable applications. Tools like Pest PHP, PHPUnit, and Laravel’s Fluent JSON Testing make this process smooth and manageable.