Skip to main content
deleted 101 characters in body
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

I've been designing and coding my Laravel API boilerplate for couple days now, and I'd like to hear some advicesadvice/improvement hints from you guys!

So, basicBasic concept:

Transfomer::item($item) basically returns a tranformedtransformed array (I'm looking forward to implicit return types in PHP7!!  )

Next, every "entity" should have it'sits own repository, which should extend my App\Support\Repository:

And of course, every "entity" must have it's own model, but I haven't created any BaseModelBaseModel class yet. I do not find it necessary right now.

As you can see in the ApiControllerApiController, I've created some custom response macros that correspond to HTTP status codes.

Also, any validation is managed through Laravel's FormRequestFormRequest class.

All in all, are there any approaches, that you consider badly implemented? AnythingIs there anything that breaks SOLID principals? AnythingIs there anything I could improve on? Any breaks PSR-2 formatting?

Thank you, for all your responses. Looking forward to your suggestions :)

I've been designing and coding my Laravel API boilerplate for couple days now, and I'd like to hear some advices/improvement hints from you guys!

So, basic concept:

Transfomer::item($item) basically returns a tranformed array ( looking forward to implicit return types in PHP7!!  )

Next, every "entity" should have it's own repository, which should extend my App\Support\Repository:

And of course, every "entity" must have it's own model, but I haven't created any BaseModel class yet. I do not find it necessary right now.

As you can see in the ApiController, I've created some custom response macros that correspond to HTTP status codes.

Also, any validation is managed through Laravel's FormRequest class.

All in all, are there any approaches, that you consider badly implemented? Anything that breaks SOLID principals? Anything I could improve? Any breaks PSR-2 formatting?

Thank you, for all your responses. Looking forward to your suggestions :)

I've been designing and coding my Laravel API boilerplate for couple days now, and I'd like to hear some advice/improvement hints!

Basic concept:

Transfomer::item($item) basically returns a transformed array (I'm looking forward to implicit return types in PHP7!)

Next, every "entity" should have its own repository, which should extend my App\Support\Repository:

And of course, every "entity" must have it's own model, but I haven't created any BaseModel class yet. I do not find it necessary right now.

As you can see in the ApiController, I've created some custom response macros that correspond to HTTP status codes.

Also, any validation is managed through Laravel's FormRequest class.

All in all, are there any approaches that you consider badly implemented? Is there anything that breaks SOLID principals? Is there anything I could improve on? Any breaks PSR-2 formatting?

Source Link

Laravel API design

I've been designing and coding my Laravel API boilerplate for couple days now, and I'd like to hear some advices/improvement hints from you guys!

I'm pretty satisfied with the result, but I'm also aware, there might be (and surely are) some things that can be improved.

So, basic concept:

Every controller should extend my App\Http\Controllers\ApiController (actually, I'm thinking about moving this controller to App\Support\Http\Controllers\ApiController):

<?php

namespace App\Http\Controllers;

use App\Support\Http\Controller;
use Illuminate\Http\Request;

abstract class ApiController extends Controller
{
    protected static $repository = null;
    protected static $transformer = null;
    protected static $storeRequest = null;
    protected static $updateRequest = null;

    public function index()
    {
        $instances   = $this->repository()->all();
        $transformed = $this->transformer()->collection($instances);

        return response()->ok($transformed);
    }

    public function show($id)
    {
        $instance    = $this->repository()->show($id);
        $transformed = $this->transformer()->item($instance);

        return response()->ok($transformed);
    }

    public function store(Request $request)
    {
        $this->validateStoreRequest();

        $this->repository()->store($request->input());

        return response()->created();
    }

    public function update(Request $request, $id)
    {
        $this->validateStoreRequest();

        $this->repository()->update($id, $request->input());

        return response()->updated();
    }

    public function destroy($id)
    {
        $this->repository()->destroy($id);

        return response()->destroyed();
    }

    private function validateStoreRequest()
    {
        app(
            static::$storeRequest ?: app('naming')->parse(static::class)->storeRequest()
        );
    }

    private function validateUpdateRequest()
    {
        app(
            static::$storeRequest ?: app('naming')->parse(static::class)->updateRequest()
        );
    }

    private function transformer()
    {
        return app(
            static::$transformer ?: app('naming')->parse(static::class)->transformer()
        );
    }

    private function repository()
    {
        return app(
            static::$repository ?: app('naming')->parse(static::class)->repository()
        );
    }
}

As you can see, every "entity" should have it's own transformer with should extends my App\Support\Transformer:

<?php

namespace App\Support;

abstract class Transformer
{
    abstract public function item($item);

    public function collection($collection)
    {
        $transformed = [];

        foreach($collection as $item) {
            $transformed[] = $this->item($item);
        }

        return $transformed;
    }
}

Transfomer::item($item) basically returns a tranformed array ( looking forward to implicit return types in PHP7!! )

Next, every "entity" should have it's own repository, which should extend my App\Support\Repository:

<?php

namespace App\Support;

abstract class Repository
{
    public function all()
    {
        $model = $this->model();

        return $model::all();
    }

    public function show($id)
    {
        $model = $this->model();

        return $model::findOrFail($id);
    }

    public function store(array $attributes)
    {
        $model = $this->model();

        return $model::create($attributes);
    }

    public function update($id, array $attributes)
    {
        $model = $this->model();

        return $model::findOrFail($id)
                        ->update($attributes);
    }

    public function destroy($id)
    {
        $model = $this->model();

        return $model::findOrFail($id)
                        ->delete();
    }

    private function model()
    {
        return app('naming')->parse(static::class)
                            ->model();
    }
}

And of course, every "entity" must have it's own model, but I haven't created any BaseModel class yet. I do not find it necessary right now.

As you can see in the ApiController, I've created some custom response macros that correspond to HTTP status codes.

You might be curious about app('naming'), but all that does, is that is transforms any class name (also full namespaced) to corresponding class for given "entity".

Also, any validation is managed through Laravel's FormRequest class.

All in all, are there any approaches, that you consider badly implemented? Anything that breaks SOLID principals? Anything I could improve? Any breaks PSR-2 formatting?

Thank you, for all your responses. Looking forward to your suggestions :)