架构图

1、Request log 申请报文日志,这里加申请报文的起因是,很多状况下的BUG是低频难复现的。原申请报文能很好的排查问题。这一层也能够放在中间件(Middleware)来解决 参考示例:

<?phpnamespace App\Http\Middleware;use App\Http\Controllers\Controller;use Closure;class ApiCheck extends Controller{    /**     * Handle an incoming request.     *     * @param  \Illuminate\Http\Request  $request     * @param  \Closure  $next     * @return mixed     */    public function handle($request, Closure $next)    {        $params = $request->input();        $Uri = $request->getRequestUri();        $UriArray = explode('?',$Uri);        $UriArray = explode('/',$UriArray[0]);        $this->dataRecodes('申请报文', $params, $UriArray[3]);        return $next($request);    }}
class Helper{    /**     * @Notes: 记录接口日志信息     * @Author: Dong Xiannan     * @Date: 2021/8/5 3:50 下午     * @Description: 形容     * @param $title     * @param $data     * @param string $file     */    public static function dataRecodes($title, $data, $file = 'log')    {        $date = date("Ymd");        if (!is_dir(storage_path('logs/' . $date))) {            mkdir(storage_path('logs/' . $date), 0777, TRUE);        }        $content = "================" . $title . ' ' . date('Y-m-d H:i:s') . "===================\n";        file_put_contents(storage_path('logs/' . $date . '/' . $file . '.log'), $content . var_export($data, 1) . PHP_EOL, 8);        return;    }

2、Middleware 中间件 不做过多阐明 全局中间件、两头组、路由中间件 依据理论场景正当利用

3、Request 层 这里我在中间件和控制器两头加了一层Request 次要用来做参数校验 示例:

class TestRequest extends BaseRequest{    public function rules()    {        return [                'nickname' => 'required',                'account_name' => 'required',                'role_id' => 'required',                'subject_id' => 'required',                'commission' => 'required',            ] + parent::rules();    }    public function messages()    {        return [            ] + parent::messages();    }    public function attributes()    {        return [                'nickname' => '昵称',                'account_name' => '账号',                'role_id' => '角色ID',                'subject_id' => '主体ID',                'commission' => '佣金比例',            ] + parent::attributes();    }}

4、Controller(控制器) 将简单的业务逻辑从控制器抽离进去放在Service(服务层)避免控制器臃肿,难懂,不易保护

class UserController extends Controller{    protected $userRepository;    protected $userService;    public function __construct(UserRepository $userRepository)    {        $this->userRepository = $userRepository;    }    /**     * Display a listing of the resource.     * @return Renderable     */    public function index(Request $request, UserService $userService, UserTransformer $userTransformer, UserFormatter $userFormatter)    {        $user = $userService->getUserAll();        return response()->json($userFormatter->format($request, $userTransformer->transform($user)));    }

5、Service层 商业逻辑,不是简略的查问数据,而是特定的工作,例如判断用户是否是会员,设置用户权限等等,这些操作倡议放在Service,之后Controller再调用它

class UserService{    protected $userRepository;    public function __construct(UserRepository $userRepository)    {        $this->userRepository = $userRepository;    }    public function getUserAll()    {        if(1 == 1){//会员           return $this->userRepository->getUaerAll();        }else{            //todo        }    }

6、Repository层 ,跟Eloquent/DB操作相干的,例如增删改查,间接和数据库打交道的根底操作抽出来放在Repository中,这样Model会变得很洁净

class UserRepository{    protected $user;    public function __construct(User $user)    {        $this->user = $user;    }    public function getUaerAll()    {        return  $this->user->all();    }

7、Transformer ,转换器,例如在仓库repository中有一个获取所有用户信息的查问操作:
$this->user->all();但有些中央咱们不须要用到那么多个字段,我只想有name和email字段,难道我要去改all()外面的参数,变成
$this->user->all(['name','email'])?这样另外的中央又要全副字段,这不就抵触了?这时候Transformer就有用了,其实原理是对$this->user->all()取得的数据进行筛选后再输入,加了个筛选器。(另外转化器还能够将输入字段和数据字段差别话,起到爱护作用,还能够去除烂尾字段id、created_at、updated_at等)

class UserTransformer{    public function transform(Collection $collection)    {        $user = $collection->map(function ($user){            return [                'name' => $user->name,                'email' => $user->email            ];        });        return $user;    }

8、Formatter 次要用于放弃API返回格局的统一

class UserFormatter{    public function format(Request $request, $items)    {        return [            'link' => $request->fullUrl(),            'method' => $request->method(),            'code' => Response::HTTP_OK,            'message' => '',            'items' => $items        ];    }

9、return log(返回报文),返回报文和申请报文是成对呈现的 放在日志零碎探讨

10、错误码:错误码须要统一化

  • 正确返回 code :0 或者 200
  • 零碎谬误 code:-1 或 500 零碎谬误是不须要给用户看的 例如数据库连贯失败等
  • 业务谬误 code: 1001、1002、1003等 业务谬误是须要给用户显示的 例如 验证码发送失败,请从新发送! 用户名明码谬误等