{"id":14974453,"url":"https://github.com/connor11528/laravel-api-example","last_synced_at":"2025-10-27T09:30:24.872Z","repository":{"id":75164514,"uuid":"106866484","full_name":"connor11528/laravel-api-example","owner":"connor11528","description":"💻 Build an API with Laravel 5","archived":false,"fork":false,"pushed_at":"2018-10-18T08:11:55.000Z","size":668,"stargazers_count":46,"open_issues_count":2,"forks_count":32,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-02-01T04:31:38.332Z","etag":null,"topics":["api","artisan","laravel","laravel-api","laravel-application","laravel-framework","laravel5","laravel55","mysql","php"],"latest_commit_sha":null,"homepage":"http://connorleech.info/blog/Use-Resource-Controller-Artisan-and-Tinker-to-set-up-REST-API-in-Laravel-5/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/connor11528.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-13T19:41:39.000Z","updated_at":"2025-01-11T17:46:38.000Z","dependencies_parsed_at":"2023-02-24T13:01:15.840Z","dependency_job_id":null,"html_url":"https://github.com/connor11528/laravel-api-example","commit_stats":{"total_commits":15,"total_committers":2,"mean_commits":7.5,"dds":0.1333333333333333,"last_synced_commit":"e6bf96df1f2f48a75b2b5524c4801e38f434badd"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connor11528%2Flaravel-api-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connor11528%2Flaravel-api-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connor11528%2Flaravel-api-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connor11528%2Flaravel-api-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/connor11528","download_url":"https://codeload.github.com/connor11528/laravel-api-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238471946,"owners_count":19478134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["api","artisan","laravel","laravel-api","laravel-application","laravel-framework","laravel5","laravel55","mysql","php"],"created_at":"2024-09-24T13:50:35.294Z","updated_at":"2025-10-27T09:30:24.456Z","avatar_url":"https://github.com/connor11528.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Laravel 5 REST API\n---\n\n\u003e Build an API with Laravel 5\n\nI'll be working alongside [this tutorial](https://www.toptal.com/laravel/restful-laravel-api-tutorial) for building the API. The author put the source code up for it [here](https://github.com/andrecastelo/example-api)\n\n## Step 1: Create the project \n\nWe can use [this handy script](https://gist.github.com/connor11528/fcfbdb63bc9633a54f40f0a66e3d3f2e) for generating a new Laravel 5 app.\n\nI also wrote [this Medium article](https://medium.com/@connorleech/build-an-online-forum-with-laravel-initial-setup-and-seeding-part-1-a53138d1fffc) that goes through installing and configuring a MySQL database for a Laravel 5 application. I find myself refering back to it regularly. \n\n## Step 2: Configure database and make models\n\nIf you don't have MySQL installed on Mac may the force be with you. It comes preinstalled and there's MAMP but getting your machine set up to run SQL to MySQL from the terminal can be tricky.\n\nMy setup is to run:\n\n```\n$ mysql -uroot -p \n\u003e create database MY_APP_NAME;\n$ php artisan make:model Article -m\n```\n\nThe `;` is required in order to end all SQL statements.\n\nAdd a **title** and **body** string columns to the articles database and run the migrations:\n\n```\n$ php artisan migrate\n```\n\nIf you get an error saying cannot connect to homestead, even after you updated your .env to not point to homestead anymore clear the config and try again.\n\nTo clear config in Laravel:\n\n```\n$ php artisan config:clear\n```\n\nMake the models fillable (Laravel will protect them by default). Add this line to **app/Article.php**:\n\n```\nprotected $fillable = ['title', 'body'];\n```\n\nFillable will allow reads and writes to those database columns. You could also set a guarded property to an empty array:\n\n```\n$guarded = []\n```\n\nWhich for our purposes will do the same thing. To learn more about this you can check the Eloquent docs on [Mass Assignment](https://laravel.com/docs/5.5/eloquent#mass-assignment).\n\n\n## Step 3: Step up a database seeders\n\nBy default we want data to play with so we must seed the database. Generate a new seeder for creating articles:\n\nCreate the articles table seeder:\n\n```\n$ php artisan make:seeder ArticlesTableSeeder\n```\n\nThat file is in **database/seeds/ArticlesTableSeeder.php**. Update it so it looks like:\n\n```\n\u003c?php\n\nuse App\\Article;\nuse Illuminate\\Database\\Seeder;\n\nclass ArticlesTableSeeder extends Seeder\n{\n    public function run()\n    {\n        // Let's truncate our existing records to start from scratch.\n        Article::truncate();\n\n        $faker = \\Faker\\Factory::create();\n\n        // And now, let's create a few articles in our database:\n        for ($i = 0; $i \u003c 50; $i++) {\n            Article::create([\n                'title' =\u003e $faker-\u003esentence,\n                'body' =\u003e $faker-\u003eparagraph,\n            ]);\n        }\n    }\n}\n```\n\nRun the database seeder:\n\n```\n$ php artisan db:seed --class=ArticlesTableSeeder\n```\n\nTo make sure it worked we can use the `artisan tinker` command. For the uninitiated there's a great intro article about the tool [on scotch.io](https://scotch.io/tutorials/tinker-with-the-data-in-your-laravel-apps-with-php-artisan-tinker).\n\nTo use it we run:\n\n```\n$ php artisan tinker \n\u003e App\\Article::all();\n```\n\nFifty articles in JSON format should fill up your console screen. Congrats we seeded the database full of articles!\n\nWe'll do nearly the same thing for the users table and then call both seeders from **database/seeds/DatabaseSeeder.php**:\n\n```\nclass DatabaseSeeder extends Seeder\n{\n    public function run()\n    {\n        $this-\u003ecall(ArticlesTableSeeder::class);\n        $this-\u003ecall(UsersTableSeeder::class);\n    }\n}\n```\n\nWe'll be able to populate both database tables by running `php artisan db:seed`.\n\nThe full users table seeder in **database/seeds/UsersTableSeeder.php` looks like:\n\n```\n\u003c?php\n\nuse Illuminate\\Database\\Seeder;\nuse App\\User;\n\nclass UsersTableSeeder extends Seeder\n{\n    /**\n     * Run the database seeds.\n     *\n     * @return void\n     */\n    public function run()\n    {\n        // Let's clear the users table first\n        User::truncate();\n\n        $faker = \\Faker\\Factory::create();\n\n        // Let's make sure everyone has the same password and \n        // let's hash it before the loop, or else our seeder \n        // will be too slow.\n        $password = Hash::make('toptal');\n\n        User::create([\n            'name' =\u003e 'Administrator',\n            'email' =\u003e 'admin@test.com',\n            'password' =\u003e $password,\n        ]);\n\n        // And now let's generate a few dozen users for our app:\n        for ($i = 0; $i \u003c 10; $i++) {\n            User::create([\n                'name' =\u003e $faker-\u003ename,\n                'email' =\u003e $faker-\u003eemail,\n                'password' =\u003e $password,\n            ]);\n        }\n    }\n}\n```\n\n## Step 4: Set up CRUD routes and controllers\n\nLaravel follows the Model View Controller (MVC) pattern that was first popularized by Ruby On Rails. We have our models set up, now we're going to set up routes that map to controllers in order to send out JSON to people (ie Javascript engines or mobile phones) that make requests to our API.\n\n```\n$ php artisan make:controller ArticleController -r\n```\n\nIn **routes/api.php** define our endpoints:\n\n```\nRoute::get('articles', 'ArticleController@index');\nRoute::get('articles/{article}', 'ArticleController@show');\nRoute::post('articles', 'ArticleController@store');\nRoute::put('articles/{article}', 'ArticleController@update');\nRoute::delete('articles/{article}', 'ArticleController@delete');\n```\n\nWe're going to take advantage of [Route Model Binding](https://laravel.com/docs/5.5/routing#route-model-binding) so that instead of passing the id and fetching by id we straight up get the resource that we want. Here is what **app/Http/Controllers/ArticleController.php** looks like w/out the comments:\n\n```\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse Illuminate\\Http\\Request;\nuse App\\Article;\n\nclass ArticleController extends Controller\n{\n    public function index()\n    {\n        return Article::all();\n    }\n\n    public function show(Article $article)\n    {\n        return $article;\n    }\n\n    public function store(Request $request)\n    {\n        $article = Article::create($request-\u003eall());\n\n        return response()-\u003ejson($article, 201);\n    }\n\n    public function update(Request $request, Article $article)\n    {\n        $article-\u003eupdate($request-\u003eall());\n\n        return response()-\u003ejson($article, 200);\n    }\n\n    public function delete(Article $article)\n    {\n        $article-\u003edelete();\n\n        return response()-\u003ejson(null, 204);\n    }\n}\n```\n\nNow we have a rudimentary API for articles. You can view in your browser all the articles: http://localhost:8000/api/articles or an individual article based on id: http://localhost:8000/api/articles/2\n\n## Step 5: Test our API with Postman\n\nInstall the Postman client [here](https://www.getpostman.com/)\n\n![Postman website home page](blob:https://imgur.com/a5b73437-dea0-4ce9-8a62-fb63c433d68e)\n\nFrom the postman client we can create get, put, post and delete requests with parameters and later on even add authorization headers. It took me a few minutes to get comfortable with their dashboard but I grew to digg it quickly. I'd heard about Postman for a long time but for whatever reason haven't incorporated it into my dev workflow. For building APIs Postman is a great tool! \n\n[Postman docs on making requests](https://www.getpostman.com/docs/postman/sending_api_requests/requests)\n\nEach request belongs to a collection so I made a test collection and defined some endpoints. \n\n![Postman initial route endpoints](https://i.imgur.com/Scsukn1.png)\n\nYou can view the API routes that I develop in this tutorial through [this link](https://www.getpostman.com/collections/0f2602a774f9d810c68e)\n\n![Easily share api endpoints you set up in Postman](https://i.imgur.com/MxsjI2v.png)\n\n## Step 6: Customize error messages (optional)\n\nBy default when a route is not found Laravel will send an HTML page that says 404 we can't find this route. If we're building an API we want to send the user JSON they can use instead of a fat HTML chunk.\n\nRedefine the `render` function in **app/Exceptions/Handler.php**:\n\n```\n    public function render($request, Exception $exception)\n    {\n        // This will replace our 404 response with\n        // a JSON response.\n        if ($exception instanceof ModelNotFoundException) {\n            return response()-\u003ejson([\n                'error' =\u003e 'Resource not found'\n            ], 404);\n        }\n\n        return parent::render($request, $exception);\n    }\n```\n\nThe header for specifying JSON responses is `Accept: application/json`\n\n## Step 7: Authentication\n\n![](https://uploads.toptal.io/blog/image/123420/toptal-blog-image-1498658670107-8278feedb09d3780de392a9cd14e03ad.png)\n\nAdd register, login and logout API routes:\n\n```\nRoute::post('register', 'Auth\\RegisterController@register');\nRoute::post('login', 'Auth\\LoginController@login');\nRoute::post('logout', 'Auth\\LoginController@logout');\n```\n\nThese controllers are in the **app/Http/Controllers/Auth** directory and ship by default with Laravel 5.\n\nIn order to implement them for an API customization required. Define the register function in **app/Http/Controllers/Auth/RegisterController.php**:\n\n```\nprotected function registered(Request $request, $user)\n{\n    $user-\u003egenerateToken();\n    return response()-\u003ejson(['data' =\u003e $user-\u003etoArray()], 201);\n}\n```\n\nAnd we define the generateToken function on the user model in **app/User.php**:\n\n```\npublic function generateToken()\n{\n    $this-\u003eapi_token = str_random(60);\n    $this-\u003esave();\n    return $this-\u003eapi_token;\n}\n```\n\nThis generates a random string that we save for the user as their unique API token.\n\nWe can test this using postman on send a curl request like so:\n\n```\n$ curl -X POST http://localhost:8000/api/register \\\n -H \"Accept: application/json\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"name\": \"John\", \"email\": \"test@register.com\", \"password\": \"toptal123\", \"password_confirmation\": \"toptal123\"}'\n```\n\nIn the **LoginController.php** define a login method:\n\n```\npublic function login(Request $request)\n{\n    $this-\u003evalidateLogin($request);\n\n    if ($this-\u003eattemptLogin($request)) {\n        $user = $this-\u003eguard()-\u003euser();\n        $user-\u003egenerateToken();\n\n        return response()-\u003ejson([\n            'data' =\u003e $user-\u003etoArray(),\n        ]);\n    }\n\n    return $this-\u003esendFailedLoginResponse($request);\n}\n```\n\nThis overwrites the trait defined in `AuthenticatesUsers`. Curl request to test login: \n\n```\n$ curl -X POST localhost:8000/api/login \\\n  -H \"Accept: application/json\" \\\n  -H \"Content-type: application/json\" \\\n  -d \"{\\\"email\\\": \\\"admin@test.com\\\", \\\"password\\\": \\\"toptal\\\" }\"\n```\n\nAuthorization token will be in the header for requests and look like `Authorization: Bearer Jll7q0BSijLOrzaOSm5Dr5hW9cJRZAJKOzvDlxjKCXepwAeZ7JR6YP5zQqnw`\n\n\n## Resources\n\n- Has email verification and API: https://medium.com/@mosesesan/tutorial-5-how-to-build-a-laravel-5-4-jwt-authentication-api-with-e-mail-verification-61d3f356f823\n+ source code: https://github.com/MosesEsan/mesan-laravel-jwt-authentication-api\n\n- :octocat: **francescomalatesta/laravel-api-boilerplate-jwt** - https://github.com/francescomalatesta/laravel-api-boilerplate-jwt - An API Boilerplate to create a ready-to-use REST API in seconds \n\n- [Create API resources with Laravel 5.5](https://medium.com/@devlob/creating-apis-in-laravel-5-5-using-api-resources-9850c1b70efb) (medium article)\n\n- [Node.js JWT auth server](https://github.com/auth0-blog/nodejs-jwt-authentication-sample) (auth0 github repo)\n\n- [Vue.js JWT auth frontend static site](https://github.com/connor11528/vuejs-auth-frontend) (github repo)\n\n- [Role base authentication in Laravel with JWT](https://scotch.io/tutorials/role-based-authentication-in-laravel-with-jwt) (scotch.io)\n\n- [boilerplate for Laravel and Vue SPA (Vue Routing + Vuetify)](https://github.com/aturingmachine/laravel-vue-spa-boilerplate) (github repo)\n\n---\n\n**Update 04/06/18:** Token based authentication for a Laravel and React.js app (uses tymon/jwt-auth package): https://medium.com/@Gbxnga/token-based-authentication-with-react-and-laravel-restful-api-83f16581e85\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconnor11528%2Flaravel-api-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconnor11528%2Flaravel-api-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconnor11528%2Flaravel-api-example/lists"}