防止在laravel中重复几乎相同的代码

qqrboqgw  于 2023-06-25  发布在  其他
关注(0)|答案(4)|浏览(115)

我的API中有一个控制器,它包含从不同的表中获取各种数据的方法,比如账户状态、账户类型等,并将其返回给API消费者。

use App\Models\AccountStatus;
use App\Models\AccountType;
use App\Models\AlertLevel;

class ClientController extends Controller
{
   public function getAccountStatuses() {
        try {
            $accountStatuses = AccountStatus::all();

            return response()->json([
                'error' => false,
                'message' => 'OK',
                'account_statuses' => $accountStatuses
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'error' => true,
                'message' => $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine()
            ], 500);
        }
    }

    public function getAccountTypes() {
        try {
            $accountTypes = AccountType::all();

            return response()->json([
                'error' => false,
                'message' => 'OK',
                'account_types' => $accountTypes
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'error' => true,
                'message' => $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine()
            ], 500);
        }
    }

    public function getAlertLevels() {
        try {
            $alertLevels = AlertLevel::all();

            return response()->json([
                'error' => false,
                'message' => 'OK',
                'alert_levels' => $alertLevels
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'error' => true,
                'message' => $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine()
            ], 500);
        }
    }
}

如何避免重复这些几乎相同的代码?

liwlm1x9

liwlm1x91#

如果你想做一些干净的代码,你应该创建一个类,它将包含一个函数来处理你的重复代码:

class ResponseBuilder
{
    public function createResponseFromData(string $dataResponseKey, $data) 
    {
        try {
            return response()->json([
                'error' => false,
                'message' => 'OK',
                $dataResponseKey => $data
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'error' => true,
                'message' => $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine()
            ], 500);
        }
    }
}

这将遵守单一责任原则,在您的控制器中,只需注入并使用它:

private ResponseBuilder $responseBuilder;

public function __construct(ResponseBuilder $responseBuilder)
{
     $this->responseBuilder = $responseBuilder; 
}

public function getAccountStatuses() 
{
     $accountStatuses = AccountStatus::all();

     return $this->responseBuilder->createResponseFromData('account_statuses', $accountStatuses);
}

你应该声明一个接口(ResponseBuilderInterface)来注入它,这样你的控制器就不负责注入了。

h7appiyu

h7appiyu2#

有很多方法可以避免重复相同的代码。这取决于开发人员的技能、知识和经验。在我的例子中,我创建了一个trait文件来处理响应。

<?php

namespace App\Http\Traits;

trait ResponseHandler {
public function successResponse($responseKey='data', $data) {
    return response()->json([
        'error' => false,
        'message' => 'OK',
        $responseKey => $data
    ]);
}

public function errorResponse($errorMessage) {
    return response()->json([
        'error' => true,
        'message' => $errorMessage
    ], 500);
}}

在Clientcontroller.php中,您可以使用ResponseHandler.php

<?php

use App\Models\AccountStatus;
use App\Models\AccountType;
use App\Models\AlertLevel;
use App\Http\Traits\ResponseHandler;

class ClientController extends Controller
{
  use ResponseHandler;
  public function getAccountStatuses()
  {
    try {
      $accountStatuses = AccountStatus::all();
      return $this->successResponse('account_types', $accountStatuses);
    } catch (\Exception $e) {
      return $this->errorResponse($e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine());
    }
  }
}

其他方式

1.尝试Repository patterns
1.试试Service Repository Pattern(我个人喜欢这个模式)
你也应该试试Eloquent:API资源这可以帮助您将模型和模型集合快速地转换为JSON。

wsewodh2

wsewodh23#

Laravel中有一个JsonResource可以帮助你构建json响应。

制作JsonResource

php artisan make:resource UserListResource

UserListResource

/**
 * Transform the resource into an array.
 *
 * @return array<string, mixed>
 */
public function toArray(Request $request): array
{
    // Defined your data structure here
    return [
        'users' => $this->resource
    ];
}

控制器

public function __invoke(Request $request)
{
    $users = $this->userService->get(); // Return a Model Collection

    // Success response
    return new UserListResource($users);
}

处理错误响应的简单示例。

制作错误资源

php artisan make:resource ErrorResource

ErrorResource

public function with(Request $request)
{
    return [
        'code'     => 999,  // error code of your system if you need
        'messages' => $this->resource->getMessage()
    ];
}

public function toArray(Request $request): array
{
    return [];
}

json解码后,响应应该是:

{
    'data': [],
    'code': 999,
    'messages': "error message"
}

异常处理

在app\Exceptions\Handler.php中

$this->renderable(function (Throwable $e, $request) {
    if ($request->is('api/*')) { // Ensure exception is during api instead of web
        return (new ExceptionResponse($e))->response()->setStatusCode(500);
    }
});

您可以从here找到该文档。

pwuypxnk

pwuypxnk4#

我们可以将这个函数存储在trait中并使用它。传递模型名称,它可以是任何你想从中获取数据的模型.在你的例子中,account_statusesaccount_typesalert_levels

public function getData($model) {
    try {
        $data = $model::all();

        return response()->json([
            'error' => false,
            'message' => 'OK',
            'account_statuses' => $data
        ]);
    } catch (\Exception $e) {
        return response()->json([
            'error' => true,
            'message' => $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine()
        ], 500);
    }
}

例如:

$accountStatus = getData('AccountStatus');
$accountType = getData('AccountType');
$alertLevels = getData('AlertLevel');

相关问题