{"id":42583874,"url":"https://github.com/reshadman/laravel-repository-response","last_synced_at":"2026-01-28T22:38:52.008Z","repository":{"id":25698974,"uuid":"29135343","full_name":"reshadman/laravel-repository-response","owner":"reshadman","description":"Make a contract on the response of your Repository class methods.","archived":false,"fork":false,"pushed_at":"2015-01-12T17:53:32.000Z","size":178,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-14T07:36:46.914Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reshadman.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-12T12:53:35.000Z","updated_at":"2018-05-26T11:51:15.000Z","dependencies_parsed_at":"2022-07-27T05:16:29.261Z","dependency_job_id":null,"html_url":"https://github.com/reshadman/laravel-repository-response","commit_stats":null,"previous_names":["bigsinoos/laravel-repository-response"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/reshadman/laravel-repository-response","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reshadman%2Flaravel-repository-response","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reshadman%2Flaravel-repository-response/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reshadman%2Flaravel-repository-response/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reshadman%2Flaravel-repository-response/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reshadman","download_url":"https://codeload.github.com/reshadman/laravel-repository-response/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reshadman%2Flaravel-repository-response/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28853744,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T15:15:36.453Z","status":"ssl_error","status_checked_at":"2026-01-28T15:15:13.020Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-28T22:38:51.909Z","updated_at":"2026-01-28T22:38:52.000Z","avatar_url":"https://github.com/reshadman.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Laravel Repository Response\nThe trend of Repository pattern made all of us to implement it in our Laravel projects. But We all have been implementing it incorrect or at least incomplete. The problem is that in true Repository pattern in addition to the input contracts( Our repositoy interfaces ) We make a deal on our method response, which is not possible in dynamic languages like PHP (It has been added to PHP7). This package helps you to implement the true pattern approximately.\n\n\u003e We should know that there is no need to implement the full true pattern, patterns have been made to solve us problems, not to be the problem itself. The incomplete pattern that is being trended is good enough for easier testing.\n\n## Installation\n\n```\ncomposer require bigsinoos/laravel-repository-response\n\n```\n\n### How it works\nThe real pattern interacts with Entities instead of our Eloquent models. so with ```Bigsinoos\\RepositoryResponse\\BaseEloquentEntity``` this problem is solved. So instead of messaging the ```Eloquent``` models, We must pass our entities. when using Eloquent Repsitories, we can put the model inside our entity which only is accssible by our ```EloquentRepository``` implementation with the help of **Friend / Sibling** classes.\n\n### Friend Classes and debug_back_trace function\n\nFriend classes in the scope of object oriented design, can break each other's encapsulation layer, for example they can call ```protected``` method of each other. PHP does not support friend classes at all.\n\nWhen we return Eloquent models from our repository methods, we allow external access to our database layer, which should be done through our repository contracts, this simply breaks the pattern, to solve this problem instead of returning Eloquent models from repository, we simply create a new Entity for the Model, and Wrap it arround the model, So everytime a method or propery is called from the entity the entity behvaes like below :\n  * Check that it is being called from a friend class or not (with debug_backtract).\n  * If so, calls the method from it's model, else it will throw an access denied exception.\n\nWhen trying to set a property on an Entity it is set on its models.\n\nBy this you can pass an Entity to multiple repositories and their eloquent models can be used as long as they are friend with each other, the friendship is defined in the eloquent implementation of the entity.\n\nBut this also breaks another rule. ** Just like as concrete implementations of reposutory classes we should define different entities for each implmenetation.** (For example ```MongoBlogeEntity```, ```EloquentBlogEntity```, ```DoctorineBlogEntity``` but as long as you make a ```BlogEntityInterface``` contract for them. there isn't any problem, at least it allows to switch between different implmentaions, which was not possible in our previous methodology (returning eloquent models from methods)).\n\n### Usage\n\nA user repository workflow will be as below :\n * UserEntityContract.php\n * EloquentUserEntity.php : this class should extends ```Bigsinoos\\RepositoryResponse\\BaseEloquentEntity``` class, to get the class friendship functionality.\n * User.php\n * UserRepositoryContract.php\n * EloquentUserRepository.php\n\nUserEntityContract.php\n\n```php\n\u003c?php\ninterface UserEntityContract {}\n```\nEloquentUserEntity.php\n```php\n\u003c?php use \\Bigsinoos\\RepositoryResponse\\BaseEloquentEntity;\n\nclass EloquentUserEntity extends BaseEloquentEntity implements \\UserEntityContract {\n        /**\n         * Friends of the user repository\n         *\n         * @var array\n         */\n        protected $friends = [\n            'EloquentUserRepository'\n        ];\n        \n        /**\n         * Get new eloquent model for each entity, it is used when you set \n         * an attribute on the entity to the entity will make an instance of the model\n         * and sets the attribute on it.\n         *\n         * @param array $attributes\n         * @return \\Illuminate\\Database\\Eloquent\\Model\n         */\n        protected function getNewModel($attributes = [])\n        {\n            return new \\User($attributes);\n        }\n    \n}\n```\n\nUser.php\n```php\n\u003c?php\n\nclass User extends \\Eloquent {\n    \n    protected $table = 'users';\n    \n}\n```\n\nUserRepositoryContract.php\n```php\ninterface UserRepositoryContract {\n    /**\n     * Finds the user gieven his/her id\n     * \n     * @param int $id\n     * @return \\UserEntityContract\n     */\n    public function findById($id);\n    \n    /**\n     * Take a collection of users\n     *\n     * @param int $howMuch\n     * @param bool $decreasing\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function take($howMuch = 10, $sortBy = 'created_at', $decreasing = true);\n}\n```\nEloquentUserRepository.php\n```php\nclass EloquentUserRepository implements UserRepositoryContract {\n    \n    protected $userEntity;\n    \n    public function __construct(\\UserEntityContract $userEntity)\n    {\n            $this-\u003euserEntity = $userEntity;\n    }\n    \n    public function findById($id)\n    {\n        $model = $this-\u003euserEntity-\u003egetModel(); // Only friend class can do this.\n        \n        $found = $model-\u003enewInstance()-\u003efindOrFail($id);\n        \n        $entity = $this-\u003euserEntity-\u003enewInstance();\n        \n        $entity-\u003esetModel($found); // Only friend class can do this.\n        \n        return $entity;\n    }\n    \n    public function take($howMuch = 10, $sortBy = 'created_at', $decreasing = true)\n    {\n        $collection = $this-\u003euserEntity\n            -\u003egetModel()\n            -\u003enewInstance()\n            -\u003eorderBy($sortBy, ((bool) $decreasing) ? 'desc' ? 'asc')\n            -\u003etake((int) $howMuch)-\u003eget();\n        \n        // Don't do this for large data sets.\n        return $this-\u003ebuildEntityCollection($collection);\n    }\n    \n    protected function buildEntityCollection(\\Illuminate\\Support\\Collection $collection)\n    {\n        $class = 'Illuminate\\Support\\Collection';\n        $items = [];\n        \n        $collection-\u003eeach(function($item)){\n        \n                $entity = $this-\u003euserEntity-\u003enewInstance();\n                \n                $entity-\u003esetModel($item);\n                \n                $items [] = $entity;\n        });\n        return app($class)-\u003emake($items);\n    }\n}\n```\nExampleController.php\n```php\nclass ExampleController extends \\BaseController {\n    \n    protected $userRepo;\n    \n    public function __construct(\\UserRepositoryContract $userRepo)\n    {\n        $this-\u003euserRepo = $userRepo;\n    }\n    \n    public function show($id)\n    {\n        $user = $this-\u003euserRepo-\u003efindById($id);\n        \n        // $user-\u003egetModel(); throws a MethodNotAllowedException\n        // $user-\u003edelete(); throws a MethodNotAllowedException\n        // $user-\u003esomethingStupid(); throws as MethodNotFoundException\n        \n        return view('user', compact('user');\n    }\n}\n```\n### Exceptions\n * ```Bigsinoos\\RepositoryResponse\\Exceptions\\EntityExceptionInterface``` all exceptions are implmenting this contract.\n * ```Bigsinoos\\RepositoryResponse\\Exceptions\\EntityException``` a basic implmentation of the above contract, for unexpected behaviours.\n * ```Bigsinoos\\RepositoryResponse\\Exceptions\\MethodNotAllowedException``` if the eloquent model is tried to being accessed outside a friend class this will be thrown.\n * ```Bigsinoos\\RepositoryResponse\\Exceptions\\MethodNotAllowedException``` if the requested could not be found on the model class this will be thrown.\n \n\u003e It is really OK to return simple eloquent models from method respositories, they are very usefull when we want to write tests, but they don't allow us to switch between different implmenetation becauase we are breaking the pattern.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freshadman%2Flaravel-repository-response","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freshadman%2Flaravel-repository-response","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freshadman%2Flaravel-repository-response/lists"}