Skip to content

Commit 46d5ebd

Browse files
committed
wip
1 parent 40776bc commit 46d5ebd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3020
-1016
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
composer.lock
22
vendor
3+
.phpunit.result.cache

README.md

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,27 @@ composer require tobyz/json-api-server
1212
```
1313

1414
```php
15-
use Tobyz\JsonApiServer\Api;
1615
use Tobyz\JsonApiServer\Adapter\EloquentAdapter;
17-
use Tobyz\JsonApiServer\Schema\Builder;
16+
use Tobyz\JsonApiServer\JsonApi;
17+
use Tobyz\JsonApiServer\Schema\Type;
1818

19-
$api = new Api('http://example.com/api');
19+
$api = new JsonApi('http://example.com/api');
2020

21-
$api->resource('articles', new EloquentAdapter(new Article), function (Builder $schema) {
22-
$schema->attribute('title');
23-
$schema->hasOne('author', 'people');
24-
$schema->hasMany('comments');
21+
$api->resource('articles', new EloquentAdapter(Article::class), function (Type $type) {
22+
$type->attribute('title');
23+
$type->hasOne('author')->type('people');
24+
$type->hasMany('comments');
2525
});
2626

27-
$api->resource('people', new EloquentAdapter(new User), function (Builder $schema) {
28-
$schema->attribute('firstName');
29-
$schema->attribute('lastName');
30-
$schema->attribute('twitter');
27+
$api->resource('people', new EloquentAdapter(User::class), function (Type $type) {
28+
$type->attribute('firstName');
29+
$type->attribute('lastName');
30+
$type->attribute('twitter');
3131
});
3232

33-
$api->resource('comments', new EloquentAdapter(new Comment), function (Builder $schema) {
34-
$schema->attribute('body');
35-
$schema->hasOne('author', 'people');
33+
$api->resource('comments', new EloquentAdapter(Comment::class), function (Type $type) {
34+
$type->attribute('body');
35+
$type->hasOne('author')->type('people');
3636
});
3737

3838
/** @var Psr\Http\Message\ServerRequestInterface $request */
@@ -60,9 +60,9 @@ The schema definition is extremely powerful and lets you easily apply [permissio
6060
### Handling Requests
6161

6262
```php
63-
use Tobyz\JsonApiServer\Api;
63+
use Tobyz\JsonApiServer\JsonApi;
6464

65-
$api = new Api('http://example.com/api');
65+
$api = new JsonApi('http://example.com/api');
6666

6767
try {
6868
$response = $api->handle($request);
@@ -71,26 +71,26 @@ try {
7171
}
7272
```
7373

74-
`Tobyz\JsonApiServer\Api` is a [PSR-15 Request Handler](https://www.php-fig.org/psr/psr-15/). Instantiate it with your API's base URL. Convert your framework's request object into a [PSR-7 Request](https://www.php-fig.org/psr/psr-7/#321-psrhttpmessageserverrequestinterface) implementation, then let the `Api` handler take it from there. Catch any exceptions and give them back to `Api` if you want a JSON:API error response.
74+
`Tobyz\JsonApiServer\JsonApi` is a [PSR-15 Request Handler](https://www.php-fig.org/psr/psr-15/). Instantiate it with your API's base URL. Convert your framework's request object into a [PSR-7 Request](https://www.php-fig.org/psr/psr-7/#321-psrhttpmessageserverrequestinterface) implementation, then let the `JsonApi` handler take it from there. Catch any exceptions and give them back to `JsonApi` if you want a JSON:API error response.
7575

7676
### Defining Resources
7777

7878
Define your API's resources using the `resource` method. The first argument is the [resource type](https://jsonapi.org/format/#document-resource-object-identification). The second is an instance of `Tobyz\JsonApiServer\Adapter\AdapterInterface` which will allow the handler to interact with your models. The third is a closure in which you'll build the schema for your resource.
7979

8080
```php
81-
use Tobyz\JsonApiServer\Schema\Builder;
81+
use Tobyz\JsonApiServer\Schema\Type;
8282

83-
$api->resource('comments', $adapter, function (Builder $schema) {
83+
$api->resource('comments', $adapter, function (Schema $schema) {
8484
// define your schema
8585
});
8686
```
8787

88-
We provide an `EloquentAdapter` to hook your resources up with Laravel [Eloquent](https://laravel.com/docs/5.8/eloquent) models. Set it up with an instance of the model that your resource represents. You can [implement your own adapter](https://github.com/tobyz/json-api-server/blob/master/src/Adapter/AdapterInterface.php) if you use a different ORM.
88+
We provide an `EloquentAdapter` to hook your resources up with Laravel [Eloquent](https://laravel.com/docs/5.8/eloquent) models. Set it up with the name of the model that your resource represents. You can [implement your own adapter](https://github.com/tobyz/json-api-server/blob/master/src/Adapter/AdapterInterface.php) if you use a different ORM.
8989

9090
```php
9191
use Tobyz\JsonApiServer\Adapter\EloquentAdapter;
9292

93-
$adapter = new EloquentAdapter(new User);
93+
$adapter = new EloquentAdapter(User::class);
9494
```
9595

9696
### Attributes
@@ -116,10 +116,10 @@ $schema->hasOne('user');
116116
$schema->hasMany('comments');
117117
```
118118

119-
By default the [resource type](https://jsonapi.org/format/#document-resource-object-identification) that the relationship corresponds to will be derived from the relationship name. In the example above, the `user` relationship would correspond to the `users` resource type, while `comments` would correspond to `comments`. If you'd like to use a different resource type, provide it as a second argument:
119+
By default the [resource type](https://jsonapi.org/format/#document-resource-object-identification) that the relationship corresponds to will be derived from the relationship name. In the example above, the `user` relationship would correspond to the `users` resource type, while `comments` would correspond to `comments`. If you'd like to use a different resource type, call the `type` method:
120120

121121
```php
122-
$schema->hasOne('author', 'people');
122+
$schema->hasOne('author')->type('people');
123123
```
124124

125125
Like attributes, the relationship will automatically read and write to the relation on your model with the same name. If you'd like it to correspond to a different relation, provide it as a third argument.
@@ -173,14 +173,14 @@ $schema->hasOne('user')
173173

174174
#### Polymorphic Relationships
175175

176-
Define polymorphic relationships on your resource using the `morphOne` and `morphMany` methods:
176+
Define a relationship as polymorphic using the `polymorphic` method:
177177

178178
```php
179-
$schema->morphOne('commentable');
180-
$schema->morphMany('taggable');
179+
$schema->hasOne('commentable')->polymorphic();
180+
$schema->hasMany('taggable')->polymorphic();
181181
```
182182

183-
Polymorphic relationships do not accept a second argument for the resource type, because it will be automatically derived from each related resource. Nested includes cannot be requested on these relationships.
183+
This will mean that the resource type associated with the relationship will be derived from the model of each related resource. Consequently, nested includes cannot be requested on these relationships.
184184

185185
### Getters
186186

@@ -257,7 +257,6 @@ $schema->attribute('email')
257257

258258
You can provide a default value for a field to be used when creating a new resource if there is no value provided by the consumer. Pass a value or a closure to the `default` method:
259259

260-
261260
```php
262261
$schema->attribute('joinedAt')
263262
->default(new DateTime);
@@ -299,7 +298,7 @@ $schema->hasMany('groups')
299298
You can easily use Laravel's [Validation](https://laravel.com/docs/5.8/validation) component for field validation with the `rules` function:
300299

301300
```php
302-
use Tobyz\JsonApi\Server\Laravel\rules;
301+
use Tobyz\JsonApiServer\Laravel\rules;
303302

304303
$schema->attribute('username')
305304
->validate(rules('required', 'min:3', 'max:30'));
@@ -312,7 +311,7 @@ Use the `set` method to define custom mutation logic for your field, instead of
312311
```php
313312
$schema->attribute('firstName')
314313
->set(function ($model, $value, $request) {
315-
return $model->first_name = strtolower($value);
314+
$model->first_name = strtolower($value);
316315
});
317316
```
318317

@@ -396,6 +395,14 @@ You can set a default sort string to be used when the consumer has not supplied
396395
$schema->defaultSort('-updatedAt,-createdAt');
397396
```
398397

398+
To define sortable criteria that does not correspond to an attribute, use the `sort` method:
399+
400+
```php
401+
$schema->sort('relevance', function ($query, $direction, $request) {
402+
$query->orderBy('relevance', $direction);
403+
});
404+
```
405+
399406
### Pagination
400407

401408
By default, resource listings are automatically [paginated](https://jsonapi.org/format/#fetching-pagination) with 20 records per page. You can change this limit using the `paginate` method on the schema builder, or you can remove it by passing `null`:
@@ -434,17 +441,19 @@ $schema->meta('requestTime', function ($request) {
434441

435442
### Creating Resources
436443

437-
By default, resources are not [creatable](https://jsonapi.org/format/#crud-creating) (i.e. `POST` requests will return `403 Forbidden`). You can allow them to be created using the `creatable` and `notCreatable` methods on the schema builder:
444+
By default, resources are not [creatable](https://jsonapi.org/format/#crud-creating) (i.e. `POST` requests will return `403 Forbidden`). You can allow them to be created using the `creatable` and `notCreatable` methods on the schema builder. Pass a closure that returns `true` if the resource should be creatable, or no value to have it always creatable.
438445

439446
```php
447+
$schema->creatable();
448+
440449
$schema->creatable(function ($request) {
441450
return $request->getAttribute('isAdmin');
442451
});
443452
```
444453

445454
#### Customizing the Model
446455

447-
When creating a resource, an empty model is supplied by the adapter. You may wish to provide a custom model in special circumstances. You can do so using the `create` method:
456+
When creating a resource, an empty model is supplied by the adapter. You may wish to override this and provide a custom model in special circumstances. You can do so using the `create` method:
448457

449458
```php
450459
$schema->create(function ($request) {
@@ -457,6 +466,8 @@ $schema->create(function ($request) {
457466
By default, resources are not [updatable](https://jsonapi.org/format/#crud-updating) (i.e. `PATCH` requests will return `403 Forbidden`). You can allow them to be updated using the `updatable` and `notUpdatable` methods on the schema builder:
458467

459468
```php
469+
$schema->updatable();
470+
460471
$schema->updatable(function ($request) {
461472
return $request->getAttribute('isAdmin');
462473
});
@@ -467,6 +478,8 @@ $schema->updatable(function ($request) {
467478
By default, resources are not [deletable](https://jsonapi.org/format/#crud-deleting) (i.e. `DELETE` requests will return `403 Forbidden`). You can allow them to be deleted using the `deletable` and `notDeletable` methods on the schema builder:
468479

469480
```php
481+
$schema->deletable();
482+
470483
$schema->deletable(function ($request) {
471484
return $request->getAttribute('isAdmin');
472485
});

composer.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@
1818
"autoload": {
1919
"psr-4": {
2020
"Tobyz\\JsonApiServer\\": "src/"
21-
}
21+
},
22+
"files": ["src/functions.php"]
2223
},
2324
"autoload-dev": {
2425
"psr-4": {
2526
"Tobyz\\Tests\\JsonApiServer\\": "tests/"
2627
}
2728
},
2829
"require-dev": {
29-
"phpunit/phpunit": "^7.4"
30+
"dms/phpunit-arraysubset-asserts": "^0.1.0",
31+
"helmich/phpunit-json-assert": "^3.0",
32+
"phpunit/phpunit": "^8.0"
3033
},
3134
"config": {
3235
"sort-packages": true

0 commit comments

Comments
 (0)