napp / apicore
API core for projects
Installs: 6 446
Dependents: 2
Suggesters: 0
Security: 0
Stars: 2
Watchers: 5
Forks: 2
Open Issues: 0
Requires
- php: ^7.2|^8.0
- ext-json: *
- illuminate/container: ^5.8|^6.0|^7.0|^8.0
- illuminate/contracts: ^5.8|^6.0|^7.0|^8.0
- illuminate/database: ^5.8|^6.0|^7.0|^8.0
- illuminate/http: ^5.8|^6.0|^7.0|^8.0
- illuminate/pagination: ^5.8|^6.0|^7.0|^8.0
- illuminate/routing: ^5.8|^6.0|^7.0|^8.0
- illuminate/support: ^5.8|^6.0|^7.0|^8.0
- illuminate/validation: ^5.8|^6.0|^7.0|^8.0
Requires (Dev)
- fakerphp/faker: ^1.10
- friendsofphp/php-cs-fixer: ^2.16
- mockery/mockery: ^1.3
- orchestra/database: ^5.1
- orchestra/testbench: ^5.0|^6.3
- phpunit/phpcov: ^6.0|^7.0|^8.0
- phpunit/phpunit: ^8.0|^9.4
- squizlabs/php_codesniffer: ^3.5
This package is auto-updated.
Last update: 2024-10-29 04:53:26 UTC
README
Use as a foundation for APIs.
Features
- Full request cycle
- APU auth guard
- Transform request input based on model api mapping
- Validate transformed data
- Transform response output (with support for nested relationships using
TransformAware
) - Correct HTTP responses backed into ApiController
- Exception handling with two renderers (dev and prod)
- Standard Exceptions
- ETag middleware for cache responses (Not Modified 304)
- Internal Router for internal api requests
- API Proxy to use easy request handling
Usage
Transform Mapping
Being able to hide database fields from the outside exposed API. With auto type casting.
<?php use Illuminate\Database\Eloquent\Model; class Post extends Model { /** * @var array */ public $apiMapping = [ 'id' => ['newName' => 'id', 'dataType' => 'int'], 'image' => ['newName' => 'image', 'dataType' => 'string'], 'title' => ['newName' => 'name', 'dataType' => 'string'], 'description' => ['newName' => 'desc', 'dataType' => 'string'], 'created_at' => ['newName' => 'createdAt', 'dataType' => 'datetime'], 'published' => ['newName' => 'published', 'dataType' => 'boolean'], ]; }
Factory
Using a factory pattern.
<?php namespace App\Posts\Factory; use App\Posts\Models\Post; use Napp\Core\Api\Validation\ValidateTrait; class PostFactory { use ValidateTrait; /** * @param array $attributes * @param bool $validate * @return Post * @throws \Napp\Core\Api\Exceptions\Exceptions\ValidationException */ public static function create(array $attributes, $validate = true): Post { if (true === $validate) { static::validate($attributes, PostValidationRules::$createRules); } return new Post($attributes); } }
Requests
Extending the ApiRequest
will automatically transform the input and validate it if Laravel rules are defined.
<?php namespace App\Posts\Request; use App\Posts\Factory\PostValidationRules; use App\Posts\Transformer\PostTransformer; use Napp\Core\Api\Requests\ApiRequest; use Napp\Core\Api\Transformers\TransformerInterface; class StorePostRequest extends ApiRequest { /** * @return array */ public function rules(): array { return PostTransformer::$createRules; } /** * @return TransformerInterface */ protected function getTransformer(): TransformerInterface { return app(PostTransformer::class); } }
API Controllers
API Controllers can use the requests, the factory for creating a model, transforming the output and finally deliver the correct reponse.
<?php namespace App\Posts\Controllers\Api; use App\Posts\Factory\PostFactory; use App\Posts\Transformer\PostTransformer; use Napp\Core\Api\Controllers\ApiController; class PostController extends ApiController { public function show(int $id, Request $request, PostTransformer $transformer): JsonResponse { $post = $this->postRepository->find($id); if (null === $post) { return $this->responseNotFound(); } return $this->respond($transformer->transformOutput($post)); } public function store(StorePostRequest $request, PostTransformer $transformer): JsonResponse { if (/* some logic */) { return $this->responseUnauthorized(); } $post = PostFactory::create($request->validated(), false); return $this->responseCreated($transformer->transformOutput($post)); } }
Internal router
Using the Internal router to request APIs.
<?php use Napp\Core\Api\Controllers\ApiInternalController; class MyController extends ApiInternalController { public function someImportantAction() { // using API get/post/put/delete $data = $this->get('/api/v1/some/route'); $stuff = $this->post('/api/v1/new/stuff', $data); return view('my.view', compact('stuff')); } }