From 91f96ceecd74429bd6e3802d5d8570d0bd32e5de Mon Sep 17 00:00:00 2001 From: Behzad Babaei Date: Sat, 28 Mar 2020 17:07:00 +0430 Subject: [PATCH 1/3] initial commit --- .env.example | 25 +++++ .gitignore | 8 ++ app/Console/Commands/.gitkeep | 0 app/Console/Kernel.php | 29 ++++++ app/Events/Event.php | 10 ++ app/Events/ExampleEvent.php | 16 +++ app/Exceptions/Handler.php | 104 +++++++++++++++++++ app/Http/Controllers/Controller.php | 11 ++ app/Http/Controllers/OrderController.php | 49 +++++++++ app/Http/Controllers/ProductController.php | 42 ++++++++ app/Http/Middleware/Authenticate.php | 44 ++++++++ app/Http/Middleware/ExampleMiddleware.php | 20 ++++ app/Jobs/ExampleJob.php | 26 +++++ app/Jobs/Job.php | 24 +++++ app/Listeners/ExampleListener.php | 31 ++++++ app/Providers/AppServiceProvider.php | 18 ++++ app/Providers/AuthServiceProvider.php | 42 ++++++++ app/Providers/EventServiceProvider.php | 19 ++++ app/Services/OrderService.php | 44 ++++++++ app/Services/ProductService.php | 46 +++++++++ app/Traits/ApiResponse.php | 26 +++++ app/Traits/RequestService.php | 27 +++++ app/User.php | 32 ++++++ artisan | 35 +++++++ bootstrap/app.php | 114 +++++++++++++++++++++ composer.json | 45 ++++++++ config/auth.php | 22 ++++ config/services.php | 13 +++ database/factories/ModelFactory.php | 13 +++ database/migrations/.gitkeep | 0 database/seeds/DatabaseSeeder.php | 16 +++ phpunit.xml | 26 +++++ public/.htaccess | 21 ++++ public/index.php | 28 +++++ readme.md | 21 ++++ resources/views/.gitkeep | 0 routes/web.php | 32 ++++++ storage/app/.gitignore | 2 + storage/framework/cache/.gitignore | 2 + storage/framework/views/.gitignore | 2 + storage/logs/.gitignore | 2 + tests/ExampleTest.php | 21 ++++ tests/TestCase.php | 14 +++ 43 files changed, 1122 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 app/Console/Commands/.gitkeep create mode 100644 app/Console/Kernel.php create mode 100644 app/Events/Event.php create mode 100644 app/Events/ExampleEvent.php create mode 100644 app/Exceptions/Handler.php create mode 100644 app/Http/Controllers/Controller.php create mode 100644 app/Http/Controllers/OrderController.php create mode 100644 app/Http/Controllers/ProductController.php create mode 100644 app/Http/Middleware/Authenticate.php create mode 100644 app/Http/Middleware/ExampleMiddleware.php create mode 100644 app/Jobs/ExampleJob.php create mode 100644 app/Jobs/Job.php create mode 100644 app/Listeners/ExampleListener.php create mode 100644 app/Providers/AppServiceProvider.php create mode 100644 app/Providers/AuthServiceProvider.php create mode 100644 app/Providers/EventServiceProvider.php create mode 100644 app/Services/OrderService.php create mode 100644 app/Services/ProductService.php create mode 100644 app/Traits/ApiResponse.php create mode 100644 app/Traits/RequestService.php create mode 100644 app/User.php create mode 100755 artisan create mode 100644 bootstrap/app.php create mode 100644 composer.json create mode 100644 config/auth.php create mode 100644 config/services.php create mode 100644 database/factories/ModelFactory.php create mode 100644 database/migrations/.gitkeep create mode 100644 database/seeds/DatabaseSeeder.php create mode 100644 phpunit.xml create mode 100644 public/.htaccess create mode 100644 public/index.php create mode 100644 readme.md create mode 100644 resources/views/.gitkeep create mode 100644 routes/web.php create mode 100644 storage/app/.gitignore create mode 100644 storage/framework/cache/.gitignore create mode 100644 storage/framework/views/.gitignore create mode 100644 storage/logs/.gitignore create mode 100644 tests/ExampleTest.php create mode 100644 tests/TestCase.php diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..584e8be --- /dev/null +++ b/.env.example @@ -0,0 +1,25 @@ +APP_NAME=ApiGateway +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_URL=http://localhost +APP_TIMEZONE=UTC + +LOG_CHANNEL=stack +LOG_SLACK_WEBHOOK_URL= + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=lu-ms1-api_gateway +DB_USERNAME= +DB_PASSWORD= + +CACHE_DRIVER=file +QUEUE_CONNECTION=sync + + +PRODUCTS_SERVICE_BASE_URI=http://localhost:8100/api +PRODUCTS_SERVICE_SECRET= +ORDERS_SERVICE_BASE_URI=http://localhost:8200/api +ORDERS_SERVICE_SECRET= \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a98c1b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/vendor +/.idea +Homestead.json +Homestead.yaml +.env + +storage/*.key +composer.lock diff --git a/app/Console/Commands/.gitkeep b/app/Console/Commands/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php new file mode 100644 index 0000000..ad6e311 --- /dev/null +++ b/app/Console/Kernel.php @@ -0,0 +1,29 @@ +getStatusCode(); + $errorMessage = Response::$statusTexts[$errorCode]; + return $this->errorResponse($errorMessage, $errorCode); + } + + if ($exception instanceof ModelNotFoundException) { + $model = strtolower(class_basename($exception->getModel())); + return $this->errorResponse( + "Does not exist any instance of {$model} with a given id", + Response::HTTP_NOT_FOUND); + } + + if ($exception instanceof AuthorizationException) { + return $this->errorResponse( + $exception->getMessage(), + Response::HTTP_FORBIDDEN); + } + + if ($exception instanceof AuthenticationException) { + return $this->errorResponse( + $exception->getMessage(), + Response::HTTP_UNAUTHORIZED); + } + + if ($exception instanceof ValidationException) { + $errors = $exception->validator->errors()->getMessages(); + return $this->errorResponse( + $errors, + Response::HTTP_UNPROCESSABLE_ENTITY); + } + + if ($exception instanceof ClientException) { + $errorMessage = $exception->getResponse()->getBody(); + $errorCode = $exception->getCode(); + + return $this->errorMessage($errorMessage, $errorCode); + } + + + if (env('APP_DEBUG', false)) { + return parent::render($request, $exception); + } + + return $this->errorResponse( + "Unexpected error. Try later!", + Response::HTTP_INTERNAL_SERVER_ERROR); + + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php new file mode 100644 index 0000000..72350ce --- /dev/null +++ b/app/Http/Controllers/Controller.php @@ -0,0 +1,11 @@ +orderService = $orderService; + $this->productService = $productService; + } + + public function index() + { + return $this->successResponse($this->orderService->fetchOrders()); + } + + public function show($order) + { + return $this->successResponse($this->orderService->fetchOrder($order)); + } + + public function store(Request $request) + { + $result = $this->productService->fetchProduct($request->product_id); +// dd($result); + + return $this->successResponse($this->orderService->createOrder($request->all())); + } + + public function update(Request $request, $order) + { + return $this->successResponse($this->orderService->updateOrder($order, $request->all())); + } + + public function destroy($order) + { + return $this->successResponse($this->orderService->deleteOrder($order)); + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php new file mode 100644 index 0000000..a7e1fe3 --- /dev/null +++ b/app/Http/Controllers/ProductController.php @@ -0,0 +1,42 @@ +productService = $productService; + } + + public function index() + { + return $this->successResponse($this->productService->fetchProducts()); + } + + public function show($product) + { + return $this->successResponse($this->productService->fetchProduct($product)); + } + + public function store(Request $request) + { + return $this->successResponse($this->productService->createProduct($request->all())); + } + + public function update(Request $request, $product) + { + return $this->successResponse($this->productService->updateProduct($product, $request->all())); + } + + public function destroy($product) + { + return $this->successResponse($this->productService->deleteProduct($product)); + } +} \ No newline at end of file diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php new file mode 100644 index 0000000..361a11e --- /dev/null +++ b/app/Http/Middleware/Authenticate.php @@ -0,0 +1,44 @@ +auth = $auth; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string|null $guard + * @return mixed + */ + public function handle($request, Closure $next, $guard = null) + { + if ($this->auth->guard($guard)->guest()) { + return response('Unauthorized.', 401); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/ExampleMiddleware.php b/app/Http/Middleware/ExampleMiddleware.php new file mode 100644 index 0000000..166581c --- /dev/null +++ b/app/Http/Middleware/ExampleMiddleware.php @@ -0,0 +1,20 @@ +app['auth']->viaRequest('api', function ($request) { +// if ($request->input('api_token')) { +// return User::where('api_token', $request->input('api_token'))->first(); +// } +// }); + + LumenPassport::routes($this->app->router); + } +} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php new file mode 100644 index 0000000..a3d284f --- /dev/null +++ b/app/Providers/EventServiceProvider.php @@ -0,0 +1,19 @@ + [ + 'App\Listeners\ExampleListener', + ], + ]; +} diff --git a/app/Services/OrderService.php b/app/Services/OrderService.php new file mode 100644 index 0000000..26eb252 --- /dev/null +++ b/app/Services/OrderService.php @@ -0,0 +1,44 @@ +baseUri = config('services.orders.base_uri'); + $this->secret = config('services.orders.secret'); + } + + public function fetchOrders() + { + return $this->request('GET', '/api/order'); + } + + public function fetchOrder($order) + { + return $this->request('GET', "/api/order/{$order}"); + } + + public function createOrder($data) + { + return $this->request('POST', '/api/order', $data); + } + + public function updateOrder($order, $data) + { + return $this->request('PATCH', "/api/order/{$order}", $data); + } + + public function deleteOrder($order) + { + return $this->request('DELETE', "/api/order/{$order}"); + } +} \ No newline at end of file diff --git a/app/Services/ProductService.php b/app/Services/ProductService.php new file mode 100644 index 0000000..89be091 --- /dev/null +++ b/app/Services/ProductService.php @@ -0,0 +1,46 @@ +baseUri = config('services.products.base_uri'); + $this->secret = config('services.products.secret'); + } + + + public function fetchProducts() + { + return $this->request('GET', '/api/product'); + } + + public function fetchProduct($product) + { + return $this->request('GET', "/api/product/{$product}"); + } + + public function createProduct($data) + { + return $this->request('POST', '/api/product', $data); + } + + public function updateProduct($product, $data) + { + return $this->request('PATCH', "/api/product/{$product}", $data); + } + + public function deleteProduct($product) + { + return $this->request('DELETE', "/api/product/{$product}"); + } + +} \ No newline at end of file diff --git a/app/Traits/ApiResponse.php b/app/Traits/ApiResponse.php new file mode 100644 index 0000000..bc022ac --- /dev/null +++ b/app/Traits/ApiResponse.php @@ -0,0 +1,26 @@ +header('Content-Type', 'application/json'); + } + + public function errorResponse($errorMessage, $statusCode) + { + return response()->json(['error' => $errorMessage, 'error_code' => $statusCode], $statusCode); + } + + public function errorMessage($errorMessage, $statusCode) + { + return response($errorMessage, $statusCode)->header('Content-Type', 'application/json'); + } +} \ No newline at end of file diff --git a/app/Traits/RequestService.php b/app/Traits/RequestService.php new file mode 100644 index 0000000..5177448 --- /dev/null +++ b/app/Traits/RequestService.php @@ -0,0 +1,27 @@ + $this->baseUri + ]); + if (isset($this->secret)) { + $headers['Authorization'] = $this->secret; + } + $response = $client->request($method, $requestUrl, + [ + 'form_params' => $formParams, + 'headers' => $headers + ] + ); + return $response->getBody()->getContents(); + } + +} \ No newline at end of file diff --git a/app/User.php b/app/User.php new file mode 100644 index 0000000..5bdef8b --- /dev/null +++ b/app/User.php @@ -0,0 +1,32 @@ +make( + 'Illuminate\Contracts\Console\Kernel' +); + +exit($kernel->handle(new ArgvInput, new ConsoleOutput)); diff --git a/bootstrap/app.php b/bootstrap/app.php new file mode 100644 index 0000000..98a15e2 --- /dev/null +++ b/bootstrap/app.php @@ -0,0 +1,114 @@ +load(); +} catch (Dotenv\Exception\InvalidPathException $e) { + // +} + +/* +|-------------------------------------------------------------------------- +| Create The Application +|-------------------------------------------------------------------------- +| +| Here we will load the environment and create the application instance +| that serves as the central piece of this framework. We'll use this +| application as an "IoC" container and router for this framework. +| +*/ + +$app = new Laravel\Lumen\Application( + dirname(__DIR__) +); + + $app->withFacades(); + + $app->withEloquent(); + + + $app->configure('services'); + $app->configure('auth'); + +/* +|-------------------------------------------------------------------------- +| Register Container Bindings +|-------------------------------------------------------------------------- +| +| Now we will register a few bindings in the service container. We will +| register the exception handler and the console kernel. You may add +| your own bindings here if you like or you can make another file. +| +*/ + +$app->singleton( + Illuminate\Contracts\Debug\ExceptionHandler::class, + App\Exceptions\Handler::class +); + +$app->singleton( + Illuminate\Contracts\Console\Kernel::class, + App\Console\Kernel::class +); + +/* +|-------------------------------------------------------------------------- +| Register Middleware +|-------------------------------------------------------------------------- +| +| Next, we will register the middleware with the application. These can +| be global middleware that run before and after each request into a +| route or middleware that'll be assigned to some specific routes. +| +*/ + +// $app->middleware([ +// App\Http\Middleware\ExampleMiddleware::class +// ]); + + $app->routeMiddleware([ + 'auth' => App\Http\Middleware\Authenticate::class, + 'client.credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class, + ]); + + + +/* +|-------------------------------------------------------------------------- +| Register Service Providers +|-------------------------------------------------------------------------- +| +| Here we will register all of the application's service providers which +| are used to bind services into the container. Service providers are +| totally optional, so you are not required to uncomment this line. +| +*/ + +// $app->register(App\Providers\AppServiceProvider::class); + $app->register(App\Providers\AuthServiceProvider::class); +// $app->register(App\Providers\EventServiceProvider::class); + + +$app->register(Laravel\Passport\PassportServiceProvider::class); +$app->register(Dusterio\LumenPassport\PassportServiceProvider::class); + + +/* +|-------------------------------------------------------------------------- +| Load The Application Routes +|-------------------------------------------------------------------------- +| +| Next we will include the routes file so that they can all be added to +| the application. This will provide all of the URLs the application +| can respond to, as well as the controllers that may handle them. +| +*/ + +$app->router->group([ + 'namespace' => 'App\Http\Controllers', +], function ($router) { + require __DIR__.'/../routes/web.php'; +}); + +return $app; diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..bdbf798 --- /dev/null +++ b/composer.json @@ -0,0 +1,45 @@ +{ + "name": "laravel/lumen", + "description": "The Laravel Lumen Framework.", + "keywords": ["framework", "laravel", "lumen"], + "license": "MIT", + "type": "project", + "require": { + "php": ">=7.1.3", + "dusterio/lumen-passport": "^0.2.15", + "guzzlehttp/guzzle": "^6.5", + "laravel/lumen-framework": "5.7.*", + "vlucas/phpdotenv": "~2.2" + }, + "require-dev": { + "fzaninotto/faker": "~1.4", + "phpunit/phpunit": "~7.0", + "mockery/mockery": "~1.0" + }, + "autoload": { + "classmap": [ + "database/seeds", + "database/factories" + ], + "psr-4": { + "App\\": "app/" + } + }, + "autoload-dev": { + "classmap": [ + "tests/" + ] + }, + "scripts": { + "post-root-package-install": [ + "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ] + }, + "config": { + "preferred-install": "dist", + "sort-packages": true, + "optimize-autoloader": true + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/config/auth.php b/config/auth.php new file mode 100644 index 0000000..3988d55 --- /dev/null +++ b/config/auth.php @@ -0,0 +1,22 @@ + [ + 'guard' => 'api', + 'passwords' => 'users', + ], + + 'guards' => [ + 'api' => [ + 'driver' => 'passport', + 'provider' => 'users', + ], + ], + + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => \App\User::class + ] + ] +]; \ No newline at end of file diff --git a/config/services.php b/config/services.php new file mode 100644 index 0000000..66a54e1 --- /dev/null +++ b/config/services.php @@ -0,0 +1,13 @@ + [ + 'base_uri' => env('PRODUCTS_SERVICE_BASE_URI'), + 'secret' => env('PRODUCTS_SERVICE_SECRET') + ], + 'orders' => [ + 'base_uri' => env('ORDERS_SERVICE_BASE_URI'), + 'secret' => env('ORDERS_SERVICE_SECRET'), + ] +]; \ No newline at end of file diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php new file mode 100644 index 0000000..7833a68 --- /dev/null +++ b/database/factories/ModelFactory.php @@ -0,0 +1,13 @@ +call('UsersTableSeeder'); + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..b8c2751 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,26 @@ + + + + + ./tests + + + + + ./app + + + + + + + + diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..b75525b --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,21 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Handle Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..04aa086 --- /dev/null +++ b/public/index.php @@ -0,0 +1,28 @@ +run(); diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..3584cb7 --- /dev/null +++ b/readme.md @@ -0,0 +1,21 @@ +# Lumen PHP Framework + +[![Build Status](https://travis-ci.org/laravel/lumen-framework.svg)](https://travis-ci.org/laravel/lumen-framework) +[![Total Downloads](https://poser.pugx.org/laravel/lumen-framework/d/total.svg)](https://packagist.org/packages/laravel/lumen-framework) +[![Latest Stable Version](https://poser.pugx.org/laravel/lumen-framework/v/stable.svg)](https://packagist.org/packages/laravel/lumen-framework) +[![Latest Unstable Version](https://poser.pugx.org/laravel/lumen-framework/v/unstable.svg)](https://packagist.org/packages/laravel/lumen-framework) +[![License](https://poser.pugx.org/laravel/lumen-framework/license.svg)](https://packagist.org/packages/laravel/lumen-framework) + +Laravel Lumen is a stunningly fast PHP micro-framework for building web applications with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Lumen attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as routing, database abstraction, queueing, and caching. + +## Official Documentation + +Documentation for the framework can be found on the [Lumen website](https://lumen.laravel.com/docs). + +## Security Vulnerabilities + +If you discover a security vulnerability within Lumen, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed. + +## License + +The Lumen framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). diff --git a/resources/views/.gitkeep b/resources/views/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/routes/web.php b/routes/web.php new file mode 100644 index 0000000..22416ee --- /dev/null +++ b/routes/web.php @@ -0,0 +1,32 @@ +group(['prefix' => 'api', 'middleware' => ['client.credentials']], function () use ($router) { + + $router->group(['prefix' => 'product'], function () use ($router) { + $router->get('/', ['uses' => 'ProductController@index']); + $router->post('/', ['uses' => 'ProductController@store']); + $router->get('/{product}', ['uses' => 'ProductController@show']); + $router->patch('/{product}', ['uses' => 'ProductController@update']); + $router->delete('/{product}', ['uses' => 'ProductController@destroy']); + }); + + $router->group(['prefix' => 'order'], function () use ($router) { + $router->get('/', ['uses' => 'OrderController@index']); + $router->post('/', ['uses' => 'OrderController@store']); + $router->get('/{order}', ['uses' => 'OrderController@show']); + $router->patch('/{order}', ['uses' => 'OrderController@update']); + $router->delete('/{order}', ['uses' => 'OrderController@destroy']); + }); + +}); \ No newline at end of file diff --git a/storage/app/.gitignore b/storage/app/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/app/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/cache/.gitignore b/storage/framework/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/views/.gitignore b/storage/framework/views/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/views/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/logs/.gitignore b/storage/logs/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/logs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php new file mode 100644 index 0000000..1bad6ef --- /dev/null +++ b/tests/ExampleTest.php @@ -0,0 +1,21 @@ +get('/'); + + $this->assertEquals( + $this->app->version(), $this->response->getContent() + ); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..89a058d --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,14 @@ + Date: Sat, 22 Jan 2022 21:30:15 +0400 Subject: [PATCH 2/3] fixing missed step --- app/Console/Kernel.php | 10 ++-- app/Events/Event.php | 2 + app/Events/ExampleEvent.php | 5 +- app/Exceptions/Handler.php | 6 +- app/Http/Controllers/Controller.php | 2 + app/Http/Controllers/OrderController.php | 48 +++++++++++++--- app/Http/Controllers/ProductController.php | 33 ++++++++++- app/Http/Middleware/Authenticate.php | 4 ++ app/Http/Middleware/ExampleMiddleware.php | 2 + app/Jobs/ExampleJob.php | 6 +- app/Jobs/Job.php | 2 + app/Listeners/ExampleListener.php | 6 +- app/Providers/AppServiceProvider.php | 3 +- app/Providers/AuthServiceProvider.php | 17 +++--- app/Providers/EventServiceProvider.php | 2 + app/Services/OrderService.php | 51 ++++++++++++++--- app/Services/ProductService.php | 56 +++++++++++++++---- app/Traits/ApiResponse.php | 25 ++++++++- app/Traits/RequestService.php | 20 +++++-- app/User.php | 8 ++- bootstrap/app.php | 6 +- composer.json | 9 +-- config/auth.php | 4 +- config/services.php | 3 +- database/factories/ModelFactory.php | 3 +- .../2022_01_22_164518_add_users_table.php | 36 ++++++++++++ database/seeds/DatabaseSeeder.php | 5 +- database/seeds/UserTableSeeder.php | 23 ++++++++ public/index.php | 2 + routes/web.php | 4 +- 30 files changed, 330 insertions(+), 73 deletions(-) create mode 100644 database/migrations/2022_01_22_164518_add_users_table.php create mode 100644 database/seeds/UserTableSeeder.php diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index ad6e311..0d8a594 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -1,5 +1,7 @@ getStatusCode(); $errorMessage = Response::$statusTexts[$errorCode]; @@ -99,6 +102,5 @@ class Handler extends ExceptionHandler return $this->errorResponse( "Unexpected error. Try later!", Response::HTTP_INTERNAL_SERVER_ERROR); - } } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 72350ce..1838462 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -1,5 +1,7 @@ orderService = $orderService; $this->productService = $productService; } + /** + * @return mixed + */ public function index() { return $this->successResponse($this->orderService->fetchOrders()); } + /** + * @param $order + * + * @return mixed + */ public function show($order) { return $this->successResponse($this->orderService->fetchOrder($order)); } + /** + * @param \Illuminate\Http\Request $request + * + * @return mixed + */ public function store(Request $request) { - $result = $this->productService->fetchProduct($request->product_id); -// dd($result); - return $this->successResponse($this->orderService->createOrder($request->all())); } + /** + * @param \Illuminate\Http\Request $request + * @param $order + * + * @return mixed + */ public function update(Request $request, $order) { return $this->successResponse($this->orderService->updateOrder($order, $request->all())); } + /** + * @param $order + * + * @return mixed + */ public function destroy($order) { return $this->successResponse($this->orderService->deleteOrder($order)); } - -} \ No newline at end of file +} diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php index a7e1fe3..36381fe 100644 --- a/app/Http/Controllers/ProductController.php +++ b/app/Http/Controllers/ProductController.php @@ -1,5 +1,7 @@ productService = $productService; } + /** + * @return mixed + */ public function index() { return $this->successResponse($this->productService->fetchProducts()); } + /** + * @param $product + * + * @return mixed + */ public function show($product) { return $this->successResponse($this->productService->fetchProduct($product)); } + /** + * @param \Illuminate\Http\Request $request + * + * @return mixed + */ public function store(Request $request) { return $this->successResponse($this->productService->createProduct($request->all())); } + /** + * @param \Illuminate\Http\Request $request + * @param $product + * + * @return mixed + */ public function update(Request $request, $product) { return $this->successResponse($this->productService->updateProduct($product, $request->all())); } + /** + * @param $product + * + * @return mixed + */ public function destroy($product) { return $this->successResponse($this->productService->deleteProduct($product)); } -} \ No newline at end of file +} diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index 361a11e..1fea457 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -1,10 +1,14 @@ app['auth']->viaRequest('api', function ($request) { + * if ($request->input('api_token')) { + * return User::where('api_token', $request->input('api_token'))->first(); + * } + * }); * * @return void */ @@ -31,12 +36,6 @@ class AuthServiceProvider extends ServiceProvider // should return either a User instance or null. You're free to obtain // the User instance via an API token or any other method necessary. -// $this->app['auth']->viaRequest('api', function ($request) { -// if ($request->input('api_token')) { -// return User::where('api_token', $request->input('api_token'))->first(); -// } -// }); - LumenPassport::routes($this->app->router); } } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index a3d284f..0175c14 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -1,5 +1,7 @@ secret = config('services.orders.secret'); } - public function fetchOrders() + /** + * @return string + */ + public function fetchOrders() : string { return $this->request('GET', '/api/order'); } - public function fetchOrder($order) + /** + * @param $order + * + * @return string + */ + public function fetchOrder($order) : string { return $this->request('GET', "/api/order/{$order}"); } - public function createOrder($data) + /** + * @param $data + * + * @return string + */ + public function createOrder($data) : string { return $this->request('POST', '/api/order', $data); } - public function updateOrder($order, $data) + /** + * @param $order + * @param $data + * + * @return string + */ + public function updateOrder($order, $data) : string { return $this->request('PATCH', "/api/order/{$order}", $data); } - public function deleteOrder($order) + /** + * @param $order + * + * @return string + */ + public function deleteOrder($order) : string { return $this->request('DELETE', "/api/order/{$order}"); } -} \ No newline at end of file +} diff --git a/app/Services/ProductService.php b/app/Services/ProductService.php index 89be091..9e4e414 100644 --- a/app/Services/ProductService.php +++ b/app/Services/ProductService.php @@ -1,46 +1,82 @@ baseUri = config('services.products.base_uri'); $this->secret = config('services.products.secret'); } - - public function fetchProducts() + /** + * @return string + */ + public function fetchProducts() : string { return $this->request('GET', '/api/product'); } - public function fetchProduct($product) + /** + * @param $product + * + * @return string + */ + public function fetchProduct($product) : string { return $this->request('GET', "/api/product/{$product}"); } - public function createProduct($data) + /** + * @param $data + * + * @return string + */ + public function createProduct($data) : string { return $this->request('POST', '/api/product', $data); } - public function updateProduct($product, $data) + /** + * @param $product + * @param $data + * + * @return string + */ + public function updateProduct($product, $data) : string { return $this->request('PATCH', "/api/product/{$product}", $data); } - public function deleteProduct($product) + /** + * @param $product + * + * @return string + */ + public function deleteProduct($product) : string { return $this->request('DELETE', "/api/product/{$product}"); } - -} \ No newline at end of file +} diff --git a/app/Traits/ApiResponse.php b/app/Traits/ApiResponse.php index bc022ac..6a6028f 100644 --- a/app/Traits/ApiResponse.php +++ b/app/Traits/ApiResponse.php @@ -1,26 +1,45 @@ header('Content-Type', 'application/json'); } + /** + * @param $errorMessage + * @param $statusCode + * + * @return mixed + */ public function errorResponse($errorMessage, $statusCode) { return response()->json(['error' => $errorMessage, 'error_code' => $statusCode], $statusCode); } + /** + * @param $errorMessage + * @param $statusCode + * + * @return mixed + */ public function errorMessage($errorMessage, $statusCode) { return response($errorMessage, $statusCode)->header('Content-Type', 'application/json'); } -} \ No newline at end of file +} diff --git a/app/Traits/RequestService.php b/app/Traits/RequestService.php index 5177448..feaa03d 100644 --- a/app/Traits/RequestService.php +++ b/app/Traits/RequestService.php @@ -1,27 +1,39 @@ $this->baseUri ]); + if (isset($this->secret)) { $headers['Authorization'] = $this->secret; } + $response = $client->request($method, $requestUrl, [ 'form_params' => $formParams, 'headers' => $headers ] ); + return $response->getBody()->getContents(); } - -} \ No newline at end of file +} diff --git a/app/User.php b/app/User.php index 5bdef8b..0ce760e 100644 --- a/app/User.php +++ b/app/User.php @@ -1,5 +1,7 @@ load(); + (new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables( + dirname(__DIR__) + ))->bootstrap(); } catch (Dotenv\Exception\InvalidPathException $e) { // } diff --git a/composer.json b/composer.json index bdbf798..72f7028 100644 --- a/composer.json +++ b/composer.json @@ -8,13 +8,14 @@ "php": ">=7.1.3", "dusterio/lumen-passport": "^0.2.15", "guzzlehttp/guzzle": "^6.5", - "laravel/lumen-framework": "5.7.*", - "vlucas/phpdotenv": "~2.2" + "laravel/lumen-framework": "5.8.*", + "lcobucci/jwt": "3.3.3", + "vlucas/phpdotenv": "^3.3" }, "require-dev": { "fzaninotto/faker": "~1.4", - "phpunit/phpunit": "~7.0", - "mockery/mockery": "~1.0" + "mockery/mockery": "~1.0", + "phpunit/phpunit": "~7.0" }, "autoload": { "classmap": [ diff --git a/config/auth.php b/config/auth.php index 3988d55..65cd3c2 100644 --- a/config/auth.php +++ b/config/auth.php @@ -1,5 +1,7 @@ [ 'guard' => 'api', @@ -19,4 +21,4 @@ return [ 'model' => \App\User::class ] ] -]; \ No newline at end of file +]; diff --git a/config/services.php b/config/services.php index 66a54e1..6ed3ef3 100644 --- a/config/services.php +++ b/config/services.php @@ -1,5 +1,6 @@ [ @@ -10,4 +11,4 @@ return [ 'base_uri' => env('ORDERS_SERVICE_BASE_URI'), 'secret' => env('ORDERS_SERVICE_SECRET'), ] -]; \ No newline at end of file +]; diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index 7833a68..7594576 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -1,5 +1,7 @@ bigIncrements('id'); + $table->string('name', 256); + $table->string('email', 256); + $table->string('password', 512); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() : void + { + Schema::dropIfExists('users'); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 23526c9..532d795 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -1,5 +1,7 @@ call('UsersTableSeeder'); + \Illuminate\Support\Facades\Artisan::call('passport:install'); + $this->call(UserTableSeeder::class); } } diff --git a/database/seeds/UserTableSeeder.php b/database/seeds/UserTableSeeder.php new file mode 100644 index 0000000..9d9fe72 --- /dev/null +++ b/database/seeds/UserTableSeeder.php @@ -0,0 +1,23 @@ + 'user1', + 'email' => 'user1@gmail.com', + 'password' => Hash::make('123456') + ]); + } +} diff --git a/public/index.php b/public/index.php index 04aa086..adecaf5 100644 --- a/public/index.php +++ b/public/index.php @@ -1,5 +1,7 @@ group(['prefix' => 'api', 'middleware' => ['client.credentials']], func $router->delete('/{order}', ['uses' => 'OrderController@destroy']); }); -}); \ No newline at end of file +}); From 29c7677fd670337bc59d807a49b79a3e18c70cad Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 30 Sep 2022 19:23:34 +0800 Subject: [PATCH 3/3] initial commit --- .gitignore.example | 8 ++++++++ artisan | 0 routes/web.php | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .gitignore.example mode change 100755 => 100644 artisan diff --git a/.gitignore.example b/.gitignore.example new file mode 100644 index 0000000..a98c1b9 --- /dev/null +++ b/.gitignore.example @@ -0,0 +1,8 @@ +/vendor +/.idea +Homestead.json +Homestead.yaml +.env + +storage/*.key +composer.lock diff --git a/artisan b/artisan old mode 100755 new mode 100644 diff --git a/routes/web.php b/routes/web.php index aa71e55..3fa8199 100644 --- a/routes/web.php +++ b/routes/web.php @@ -13,7 +13,8 @@ declare(strict_types = 1); | */ -$router->group(['prefix' => 'api', 'middleware' => ['client.credentials']], function () use ($router) { +// $router->group(['prefix' => 'api', 'middleware' => ['client.credentials']], function () use ($router) { +$router->group(['prefix' => 'api'], function () use ($router) { $router->group(['prefix' => 'product'], function () use ($router) { $router->get('/', ['uses' => 'ProductController@index']);