diff --git a/app/JsonApi/Books/Adapter.php b/app/JsonApi/Books/Adapter.php new file mode 100644 index 0000000..ecac3ba --- /dev/null +++ b/app/JsonApi/Books/Adapter.php @@ -0,0 +1,54 @@ +filterWithScopes($query, $filters); + } + + /** + * @return \CloudCreativity\LaravelJsonApi\Eloquent\HasMany + */ + protected function chapters() + { + return $this->hasMany(); + } +} diff --git a/app/JsonApi/Books/Schema.php b/app/JsonApi/Books/Schema.php new file mode 100644 index 0000000..30eb3be --- /dev/null +++ b/app/JsonApi/Books/Schema.php @@ -0,0 +1,54 @@ +getRouteKey(); + } + + /** + * @param \App\Book $resource + * the domain record being serialized. + * @return array + */ + public function getAttributes($resource) + { + return [ + 'name' => $resource->name, + 'created-at' => $resource->created_at->toAtomString(), + 'updated-at' => $resource->updated_at->toAtomString(), + ]; + } + + /** + * @param object $resource + * @param bool $isPrimary + * @param array $includeRelationships + * @return array|\bool[][] + */ + public function getRelationships($resource, $isPrimary, array $includeRelationships) + { + return [ + 'chapters' => [ + self::SHOW_SELF => true, + self::SHOW_RELATED => true, + ] + ]; + } +} diff --git a/app/JsonApi/Chapters/Adapter.php b/app/JsonApi/Chapters/Adapter.php new file mode 100644 index 0000000..c4135b2 --- /dev/null +++ b/app/JsonApi/Chapters/Adapter.php @@ -0,0 +1,62 @@ +filterWithScopes($query, $filters); + } + + /** + * @return \CloudCreativity\LaravelJsonApi\Eloquent\HasMany + */ + protected function verses() + { + return $this->hasMany(); + } + + /** + * @return \CloudCreativity\LaravelJsonApi\Eloquent\HasOne + */ + protected function book() + { + return $this->hasOne(); + } +} diff --git a/app/JsonApi/Chapters/Schema.php b/app/JsonApi/Chapters/Schema.php new file mode 100644 index 0000000..c6272d5 --- /dev/null +++ b/app/JsonApi/Chapters/Schema.php @@ -0,0 +1,54 @@ +getRouteKey(); + } + + /** + * @param \App\Chapter $resource + * the domain record being serialized. + * @return array + */ + public function getAttributes($resource) + { + return [ + 'name' => $resource->name, + 'created-at' => $resource->created_at->toAtomString(), + 'updated-at' => $resource->updated_at->toAtomString(), + ]; + } + + /** + * @param object $resource + * @param bool $isPrimary + * @param array $includeRelationships + * @return array|\bool[][] + */ + public function getRelationships($resource, $isPrimary, array $includeRelationships) + { + return [ + 'verses' => [ + self::SHOW_SELF => true, + self::SHOW_RELATED => true, + ] + ]; + } +} diff --git a/app/JsonApi/Verses/Adapter.php b/app/JsonApi/Verses/Adapter.php new file mode 100644 index 0000000..e84d061 --- /dev/null +++ b/app/JsonApi/Verses/Adapter.php @@ -0,0 +1,62 @@ +filterWithScopes($query, $filters); + } + + /** + * @return \CloudCreativity\LaravelJsonApi\Eloquent\HasMany + */ + protected function verses() + { + return $this->hasMany(); + } + + /** + * @return \CloudCreativity\LaravelJsonApi\Eloquent\HasOne + */ + protected function chapter() + { + return $this->hasOne(); + } +} diff --git a/app/JsonApi/Verses/Schema.php b/app/JsonApi/Verses/Schema.php new file mode 100644 index 0000000..6254e20 --- /dev/null +++ b/app/JsonApi/Verses/Schema.php @@ -0,0 +1,56 @@ +getRouteKey(); + } + + /** + * @param \App\Verse $resource + * the domain record being serialized. + * @return array + */ + public function getAttributes($resource) + { + return [ + 'name' => $resource->name, + 'ulb_text' => $resource->ulb_text, + 'greek_text' => $resource->greek_text, + 'created-at' => $resource->created_at->toAtomString(), + 'updated-at' => $resource->updated_at->toAtomString(), + ]; + } + + /** + * @param object $resource + * @param bool $isPrimary + * @param array $includeRelationships + * @return array|\bool[][] + */ + public function getRelationships($resource, $isPrimary, array $includeRelationships) + { + return [ + 'words' => [ + self::SHOW_SELF => true, + self::SHOW_RELATED => true, + ] + ]; + } +} diff --git a/app/JsonApi/Words/Adapter.php b/app/JsonApi/Words/Adapter.php new file mode 100644 index 0000000..1940965 --- /dev/null +++ b/app/JsonApi/Words/Adapter.php @@ -0,0 +1,54 @@ +filterWithScopes($query, $filters); + } + + /** + * @return \CloudCreativity\LaravelJsonApi\Eloquent\HasOne + */ + protected function verse() + { + return $this->hasOne(); + } +} diff --git a/app/JsonApi/Words/Schema.php b/app/JsonApi/Words/Schema.php new file mode 100644 index 0000000..0d857ff --- /dev/null +++ b/app/JsonApi/Words/Schema.php @@ -0,0 +1,43 @@ +getRouteKey(); + } + + /** + * @param \App\Word $resource + * the domain record being serialized. + * @return array + */ + public function getAttributes($resource) + { + return [ + 'ulb' => $resource->ulb, + 'greek' => $resource->greek, + 'lemma' => $resource->lemma, + 'morph' => $resource->morph, + 'ognt_sort' => $resource->ognt_sort, + 'strongs_number' => $resource->strongs_number, + 'created-at' => $resource->created_at->toAtomString(), + 'updated-at' => $resource->updated_at->toAtomString(), + ]; + } +} diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 540d17b..c4c16db 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -72,8 +72,7 @@ class RouteServiceProvider extends ServiceProvider */ protected function mapApiRoutes() { - Route::prefix('api') - ->middleware('api') + Route::middleware('api') ->namespace($this->namespace) ->group(base_path('routes/api.php')); } diff --git a/config/json-api-default.php b/config/json-api-default.php new file mode 100644 index 0000000..f3629a8 --- /dev/null +++ b/config/json-api-default.php @@ -0,0 +1,207 @@ + \CloudCreativity\LaravelJsonApi\Resolver\ResolverFactory::class, + + /* + |-------------------------------------------------------------------------- + | Root Namespace + |-------------------------------------------------------------------------- + | + | The root namespace for JSON API classes for this API. If `null`, the + | namespace will default to `JsonApi` within your application's root + | namespace (obtained via Laravel's `Application::getNamespace()` + | method). + | + | The `by-resource` setting determines how your units are organised within + | your root namespace. + | + | - true: + | - e.g. App\JsonApi\Posts\{Adapter, Schema, Validators} + | - e.g. App\JsonApi\Comments\{Adapter, Schema, Validators} + | - false: + | - e.g. App\JsonApi\Adapters\PostAdapter, CommentAdapter} + | - e.g. App\JsonApi\Schemas\{PostSchema, CommentSchema} + | - e.g. App\JsonApi\Validators\{PostValidator, CommentValidator} + | + */ + 'namespace' => null, + 'by-resource' => true, + + /* + |-------------------------------------------------------------------------- + | Model Namespace + |-------------------------------------------------------------------------- + | + | Here you can decide where your api models live. + | By default (i.e. set to null), the package assumes they will live in + | your application's root namespace, but you could set it to something + | different here. E.g. `App\Models`. + | + */ + 'model-namespace' => null, + + /* + |-------------------------------------------------------------------------- + | Resources + |-------------------------------------------------------------------------- + | + | Here you map the list of JSON API resources in your API to the actual + | record (model/entity) classes they relate to. + | + | For example, if you had a `posts` JSON API resource, that related to + | an Eloquent model `App\Post`, your mapping would be: + | + | `'posts' => App\Post::class` + */ + 'resources' => [ + 'books' => \App\Book::class, + 'chapters' => \App\Chapter::class, + 'verses' => \App\Verse::class, + 'words' => \App\Word::class, + ], + + /* + |-------------------------------------------------------------------------- + | Eloquent + |-------------------------------------------------------------------------- + | + | Whether your JSON API resources predominantly relate to Eloquent models. + | This is used by the package's generators. + | + | You can override the setting here when running a generator. If the + | setting here is `true` running a generator with `--no-eloquent` will + | override it; if the setting is `false`, then `--eloquent` is the override. + | + */ + 'use-eloquent' => true, + + /* + |-------------------------------------------------------------------------- + | URL + |-------------------------------------------------------------------------- + | + | The API's url, made up of a host, URL namespace and route name prefix. + | + | If a JSON API is handling an inbound request, the host will always be + | detected from the inbound HTTP request. In other circumstances + | (e.g. broadcasting), the host will be taken from the setting here. + | If it is `null`, the `app.url` config setting is used as the default. + | If you set `host` to `false`, the host will never be appended to URLs + | for inbound requests. + | + | The name setting is the prefix for route names within this API. + | + */ + 'url' => [ + 'host' => null, + 'namespace' => '/api/v1', + 'name' => 'api:v1:', + ], + + /* + |-------------------------------------------------------------------------- + | Controllers + |-------------------------------------------------------------------------- + | + | The default JSON API controller wraps write operations in transactions. + | You can customise the connection for the transaction here. Or if you + | want to turn transactions off, set `transactions` to `false`. + | + */ + 'controllers' => [ + 'transactions' => true, + 'connection' => null, + ], + + /* + |-------------------------------------------------------------------------- + | Jobs + |-------------------------------------------------------------------------- + | + | Defines settings for the asynchronous processing feature. We recommend + | referring to the documentation on asynchronous processing if you are + | using this feature. + | + | Note that if you use a different model class, it must implement the + | asynchronous process interface. + | + */ + 'jobs' => [ + 'resource' => 'queue-jobs', + 'model' => \CloudCreativity\LaravelJsonApi\Queue\ClientJob::class, + ], + + /* + |-------------------------------------------------------------------------- + | Encoding Media Types + |-------------------------------------------------------------------------- + | + | This defines the JSON API encoding used for particular media + | types supported by your API. This array can contain either + | media types as values, or can be keyed by a media type with the value + | being the options that are passed to the `json_encode` method. + | + | These values are also used for Content Negotiation. If a client requests + | via the HTTP Accept header a media type that is not listed here, + | a 406 Not Acceptable response will be sent. + | + | If you want to support media types that do not return responses with JSON + | API encoded data, you can do this at runtime. Refer to the + | Content Negotiation chapter in the docs for details. + | + */ + 'encoding' => [ + 'application/vnd.api+json', + ], + + /* + |-------------------------------------------------------------------------- + | Decoding Media Types + |-------------------------------------------------------------------------- + | + | This defines the media types that your API can receive from clients. + | This array is keyed by expected media types, with the value being the + | service binding that decodes the media type. + | + | These values are also used for Content Negotiation. If a client sends + | a content type not listed here, it will receive a + | 415 Unsupported Media Type response. + | + | Decoders can also be calculated at runtime, and/or you can add support + | for media types for specific resources or requests. Refer to the + | Content Negotiation chapter in the docs for details. + | + */ + 'decoding' => [ + 'application/vnd.api+json', + ], + + /* + |-------------------------------------------------------------------------- + | Providers + |-------------------------------------------------------------------------- + | + | Providers allow vendor packages to include resources in your API. E.g. + | a Shopping Cart vendor package might define the `orders` and `payments` + | JSON API resources. + | + | A package author will define a provider class in their package that you + | can add here. E.g. for our shopping cart example, the provider could be + | `Vendor\ShoppingCart\JsonApi\ResourceProvider`. + | + */ + 'providers' => [], + +]; diff --git a/routes/api.php b/routes/api.php index bcb8b18..2fd65fa 100644 --- a/routes/api.php +++ b/routes/api.php @@ -17,3 +17,19 @@ use Illuminate\Support\Facades\Route; Route::middleware('auth:api')->get('/user', function (Request $request) { return $request->user(); }); + +JsonApi::register('default')->routes(function ($api) { + $api->resource('books')->readOnly()->relationships(function ($relations) { + $relations->hasMany('chapters')->readOnly(); + }); + + $api->resource('chapters')->readOnly()->relationships(function ($relations) { + $relations->hasMany('verses')->readOnly(); + }); + + $api->resource('verses')->readOnly()->relationships(function ($relations) { + $relations->hasMany('words')->readOnly(); + }); + + $api->resource('words')->readOnly(); +});