Blog

  • Set up Laravel with Swagger for comprehensive API documentation. Step-by-step instructions

    Set up Laravel with Swagger for comprehensive API documentation. Step-by-step instructions

    Prerequisites:

    • Laravel installed on your system.
    • Composer installed on your system.
    • Basic knowledge of Laravel and PHP.
    • A text editor or integrated development environment (IDE).

    Step 1: Create a Laravel Project

    If you don’t have a Laravel project already, create one using Composer. Open your terminal and run the following command:

    composer create-project --prefer-dist laravel/laravel your-api-project

    Replace your-api-project with your desired project name.

    Step 2: Install Swagger-PHP Library

    You’ll need the Swagger-PHP library to generate Swagger documentation. Install it using Composer:

    composer require zircote/swagger-php

    Step 3: Create API Routes

    In Laravel, define your API routes in the routes/api.php file. You can create routes as you normally would for your API.

    // routes/api.php
    
    use Illuminate\Support\Facades\Route;
    
    Route::get('/users', 'UserController@index');
    Route::post('/users', 'UserController@store');
    Route::get('/users/{id}', 'UserController@show');
    // Add more routes as needed

    Step 4: Generate Swagger Annotations

    In your controller methods, use Swagger annotations to document your API. Here’s an example of how to annotate a controller method:

    /**
     * @SWG\Get(
     *     path="/users",
     *     summary="Get a list of users",
     *     tags={"Users"},
     *     @SWG\Response(response=200, description="Successful operation"),
     *     @SWG\Response(response=400, description="Invalid request")
     * )
     */
    public function index()
    {
        // Your API logic here
    }

    You can find more information on Swagger annotations in the Swagger-PHP documentation.

    Step 5: Generate Swagger Documentation

    After annotating your controllers, you need to generate Swagger documentation. You can do this using the artisan command provided by the darkaonline/l5-swagger package.

    First, install the package:

    composer require darkaonline/l5-swagger

    Now, publish the Swagger configuration:

    php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"

    Edit the config/l5-swagger.php file to customize the Swagger configuration if needed.

    Step 6: Generate Swagger Documentation

    Run the following command to generate the Swagger documentation:

    php artisan l5-swagger:generate

    Swagger UI will be available at http://your-api-project.test/api/documentation. Replace your-api-project.test with your local development domain.

    Step 7: Access Swagger UI

    Visit the Swagger UI URL in your browser. You will see a user-friendly interface where you can explore and test your API endpoints.

    Step 8: Document Additional Endpoints

    Repeat Step 4 for any additional endpoints you want to document in your API.

    That’s it! You’ve successfully set up Laravel with Swagger for comprehensive API documentation. Keep your Swagger annotations up to date as you make changes to your API to ensure accurate documentation.

  • Goodbye SASS 👋, welcome back native CSS

    Goodbye SASS 👋, welcome back native CSS

    Sass has established itself as a powerful preprocessor installed locally, forming the backbone of my projects for over a decade. It enabled me to efficiently organize scalable and stable CSS packages. Even today, I still consider Sass to be an extraordinarily powerful tool. Yet, as we step into the year 2024, it’s undeniable that CSS has undergone rapid development. Features that were once unique to Sass are now natively integrated into CSS, including variables and the latest highlight: CSS Nesting.

    :root {
      --button-padding: 10px 20px;
      --button-bg-color: #007bff;
      --button-text-color: #ffffff;
      --button-border-radius: 8px;
    }
    
    .button {
      padding: var(--button-padding);
      background-color: var(--button-bg-color);
      color: var(--button-text-color);
      border-radius: var(--button-border-radius);
      border: none;
      cursor: pointer;
      transition: background-color 0.3s;
    }

    Defining variables was long seen as a unique strength of SCSS, allowing for the centralized management of many properties, a feature sorely missed in CSS for a long time. Today, however, variables can also be defined in CSS in a manner similar to Sass. A significant difference, however, is that Sass variables exist exclusively within the preprocessor context, while CSS variables can be used in the browser and even dynamically overwritten via JavaScript.

    CSS Nesting

    blog {
      position: relative;
      padding: 1rem;
      background: var(--neutral-100);
    
        .blog-item {
          border: 1px solid var(--neutral-200);
    
          & span {
            font-size: 1rem;
          }
      }
    }

    The ability to define the style rules of one element within another significantly simplifies writing CSS. Instead of repeatedly using the same selector for subordinate elements or pseudo-selectors, nesting allows grouping these within a parent selector. This technique leads to a clear, hierarchically structured, and thus more efficient codebase.

    With browser support of over 84% for CSS Nesting and 86% for the Nesting Selector, this technique is becoming increasingly accessible.

  • 28 JavaScript One-Liners every Senior Developer Needs to Know

    28 JavaScript One-Liners every Senior Developer Needs to Know

    1. Swapping Values Without a Temporary Variable

    let a = 1, b = 2;
    
    [a, b] = [b, a];
    
    // Output: a = 2, b = 1

    This one-liner uses array destructuring to swap the values of a and b without needing a temporary variable. It’s a neat trick that makes your code cleaner and more concise. The [a, b] = [b, a] syntax swaps their values by destructuring the array on the right-hand side and assigning it to the left-hand side.

    2. Object Destructuring for Easier Data Access

    const {name, age} = {name: 'John', age: 30};
    
    // Output: name = 'John', age = 30

    Here, object destructuring is used to extract name and age properties from an object directly into variables. This approach simplifies accessing object properties and enhances code readability.

    1. Swapping Values Without a Temporary Variable

    let a = 1, b = 2;
    
    [a, b] = [b, a];
    
    // Output: a = 2, b = 1

    This one-liner uses array destructuring to swap the values of a and b without needing a temporary variable. It’s a neat trick that makes your code cleaner and more concise. The [a, b] = [b, a] syntax swaps their values by destructuring the array on the right-hand side and assigning it to the left-hand side.

    2. Object Destructuring for Easier Data Access

    const {name, age} = {name: 'John', age: 30};
    
    // Output: name = 'John', age = 30

    Here, object destructuring is used to extract name and age properties from an object directly into variables. This approach simplifies accessing object properties and enhances code readability.

  • Building Robust Admin Panels with Filament and Laravel: A Step-by-Step Guide

    Building Robust Admin Panels with Filament and Laravel: A Step-by-Step Guide

    Laravel is a powerful PHP framework that provides a solid foundation for developing web applications. Filament is an open-source, elegant admin panel and form builder for Laravel that simplifies creating admin interfaces. This guide will walk you through building a robust admin panel using the latest versions of Filament and Laravel.

    Prerequisites

    Before we begin, ensure you have the following installed on your development machine:

    • PHP >= 8.0
    • Composer
    • Node.js and NPM
    • MySQL or any other database supported by Laravel

    Step 1: Setting Up a New Laravel Project

    First, create a new Laravel project using Composer:

    composer create-project --prefer-dist laravel/laravel filament-admin
    cd filament-admin

    Next, set up your environment variables. Rename the .env.example file to .env and update the database configuration with your credentials:

    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=filament_db
    DB_USERNAME=root
    DB_PASSWORD=your_password

    Run the following command to generate an application key and migrate the default Laravel tables:

    php artisan key:generate
    php artisan migrate
    php artisan key:generate
    php artisan migrate
  • ?? vs || in JavaScript: The little-known difference

    ?? vs || in JavaScript: The little-known difference

    Wrong. They’re not what you think.
    And we must learn the difference once and for all to avoid painful bugs down the line.
    And what’s this difference?<

    It’s the incredible contrast in how they treat truthy and falsy values.

    What are these?

    Falsy: becomes false in a Boolean() or if:

  • Write a React Component Like a Pro

    Write a React Component Like a Pro

    In the world of React, writing components is an art. It’s not just about making them work — it’s about making them work well. Today, we’re going to look at how to craft your components like a pro, focusing on readability, reusability, and efficiency.

    // src/components/List.js
    import React from 'react';
    
    const List = ({ data }) => {
      return (
        <ul>
          {data.map((item, index) => (
            <li key={index}>{item}</li>
          ))}
        </ul>
      );
    };
    
    export default List;

    This component takes an array of data and renders it as a list.

    Enhancing Components with HOCs

    Higher-Order Components (HOCs) are a powerful pattern for reusing component logic. They essentially wrap a component to extend its functionality without altering its structure.

    For example, a withLoading HOC can be used to display a loading state:

    // src/hocs/withLoading.js
    import React, { useState } from 'react';
    
    function withLoading(Component) {
      return function WithLoading({ isLoading, ...props }) {
        if (isLoading) {
          return <div>Loading...</div>;
        }
        return <Component {...props} />;
      };
    }
    
    export default withLoading;