Maison >développement back-end >tutoriel php >Conception d'une structure de référentiel évolutive dans Laravel avec queryFi

Conception d'une structure de référentiel évolutive dans Laravel avec queryFi

Linda Hamilton
Linda Hamiltonoriginal
2024-12-25 18:03:17567parcourir

Designing a Scalable Repository Structure in Laravel with queryFi

Introduction

Quand je démarrais un nouveau projet Laravel, je me demandais souvent quelle structure je devais utiliser.
Laravel est très bien structuré, ne vous méprenez pas, il est donc difficile de tout gâcher.
Cependant, il y a un problème : comment éviter de mettre toute la logique dont nous avons besoin dans un contrôleur, tel que UserController.php ?
Dans cet article, nous nous concentrerons sur cette question. Je partagerai ma structure préférée pour couvrir mes cas d'utilisation, ainsi que quelques bonnes pratiques, et expliquerai comment intégrer queryFi.


Commencer

Puisque vous êtes ici, je suppose que vous avez déjà un projet Laravel ou que vous savez comment en créer un, afin que nous puissions sauter cette étape. Assurez-vous simplement que l'API est configurée.

Nous utiliserons la structure suivante :

app
├── Repositories
|   ├── Interfaces
|   |   ├── EloquentRepositoryInterface.php
|   └── Eloquent
|       ├── BaseRepository.php
|       └── UserRepository.php
├── Resources
    ├── BaseResource.php
    └── ExtendedJsonResource.php

Vous pouvez trouver le dossier Ressources ici, ainsi qu'un enregistreur personnalisé.


1. Installez queryFi

# Backend
composer require z3rka/queryfi

# Frontend
npm i queryfi

2. Ajouter des interfaces de référentiel

<?php

namespace App\Repositories\Interfaces;

use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;

interface EloquentRepositoryInterface
{
    public function create(array $attributes = [], ?string $successMessage, ?string $errorMessage): JsonResource;

    public function all(Request $request, ?string $errorMessage): JsonResource;

    public function one(Request $request, Model $model, ?string $errorMessage): JsonResource;

    public function update(Request $request, Model $model, ?string $successMessage, ?string $errorMessage): JsonResource;

    public function destroy(Request $request, ?string $successMessage, ?string $errorMessage): JsonResource;
}


3. Ajoutez la classe du référentiel de base

Je n'ajouterai ici que trois méthodes pour garder les choses propres et éviter d'encombrer l'espace avec du code répétitif.
Vous pouvez trouver le reste ici.

<?php

namespace App\Repositories\Eloquent;

use Z3rka\Queryfi\HasRelations;

class BaseRepository implements EloquentRepositoryInterface {
    use HasRelations;

    public function __construct(protected Model $model)
    {
        //
    }

    public function create(array $attributes = [], ?string $successMessage, ?string $errorMessage): BaseResource
    {
        try {
            return new BaseResource(
                true,
                $successMessage,
                $this->model->create($attributes)
            );
        } catch (Exception $e) {
            return new BaseResource(
                false,
                $errorMessage,
                [
                    'error' => $e
                ]
            );
        }
    }

    public function all(Request $request, ?string $errorMessage): BaseResource
    {
        try {
            return new BaseResource(
              true, 
              'Success', 
              $this->processModel($request, $this->model)
            );
        } catch (Exception $e) {
            $this->spitError($e);
            return new BaseResource(
                false,
                "Fail",
                $this->model->get(),
                [
                    "error" => $e,
                ]
            );
        }
    }

    public function one(Request $request, Model $model, ?string $errorMessage): BaseResource
    {
        try {
            return new BaseResource(
              true, 
              "success", 
              $this->processModel($request, $model)
            )
        } catch (Exception $e) {
            $this->spitError($e);
            return new BaseResource(
                false,
                "Fail",
                $model,
                [
                    "error" => $e,
                ]
            );
        }
    }
}

Normalement, pour renvoyer quelque chose d'un modèle, vous devez ->get() ou find et ->first(), ce n'est pas le cas ici car nous utilisons le package queryFi et nous pouvons faire ceci :

$this->processModel($request, $this->model)

Cela couvre automatiquement ->get() par défaut si aucun getter (vérifiez les getters ici) n'est configuré dans la requête.


4. Référentiel d'utilisateurs

<?php

namespace App\Repositories\Eloquent;
use App\Models\User;
use Z3rka\Queryfi\HasRelations;

class UserRepository extends BaseRepository
{
    use HasRelations;

    public function __construct(User $model)
    {
        parent::__construct($model);
    }
}

5. Contrôleur utilisateur

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Repositories\Eloquent\UserRepository;

class UserController extends Controller
{
    public function __construct(public UserRepository $userRepository)
    {
    }

    public function index(Request $request)
    {
      return $this->userRepository
                  ->all($request, "Ooops, there was an error fetching all the users.")
    }

    public function show(Request $request, User $user)
    {
      return $this->userRepository->one(
            $request,
            $user,
            "Ooops, there was an error fetching the user."
        );
    }
}

6. La route des API

Route::resource('users', UserController::class)->only(['index', 'show'])

Une fois que tout est configuré, nous pouvons faire des requêtes depuis le navigateur en passant directement les paramètres de requête, comme :

url?where[name]=john&select=name&getter=first

Alternativement, nous pouvons utiliser le package queryFi TypeScript sur le frontend pour une approche plus propre.

import { createQuery } from "queryfi";

const query = createQuery('/api/users', {
    baseUrl: "http://localhost:8000"
  })
  .where({
    id: 1
  })
  .first() // will return an object with the user if it exists.

La requête générée ressemblera à

http://localhost:8000/api/users?where[id]=1&getter=first

Ce morceau de code renverra l'utilisateur avec l'identifiant = 1.
Lorsque vous utilisez .find(), la réponse sera automatiquement un objet.
Si vous utilisez .get(), il renverra un tableau.

Vous pouvez l'essayer dans la cour de récréation pour voir à quoi ressemble la réponse.

Puisque nous utilisons le trait HasRelations, nous pouvons enchaîner les requêtes frontend pour transformer les données directement sur le backend avant qu'elles ne soient renvoyées, comme indiqué ici.

import { createQuery } from "queryfi";

const query = createQuery('/api/users', {
    baseUrl: "http://localhost:8000"
  })
  .where({
    id: 1
  })
  .select(['email', 'id', 'name'])
  .get() // will return an array with one entry if it exists.

Pour plus de méthodes que vous pouvez utiliser, consultez la documentation queryFi


FIN

Et c'est tout ! ? Vous disposez désormais d’un point de départ solide et puissant pour créer vos API comme un pro.
Allez-y, faites travailler vos muscles du codage et créez quelque chose de génial ! ??

Entrez en contact avec github, Linkedin, queryFi

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn