8000 Merge branch 'release/2.0.0' · CodingSeo/laravel-json-api@0bd0953 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0bd0953

Browse files
committed
Merge branch 'release/2.0.0'
2 parents 4441315 + be50a45 commit 0bd0953

File tree

10 files changed

+87
-24
lines changed

10 files changed

+87
-24
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22
All notable changes to this project will be documented in this file. This project adheres to
33
[Semantic Versioning](http://semver.org/) and [this changelog format](http://keepachangelog.com/).
44

5+
## [2.0.0] - 2020-06-17
6+
7+
### Added
8+
- Translation files can now be published using the `vendor:publish` Artisan command.
9+
10+
### Fixed
11+
- [#506](https://github.com/cloudcreativity/laravel-json-api/pull/506)
12+
Resolve model bindings correctly when substituting URL parameters.
13+
- Updated type-hinting for `Responses::errors()` method and allowed a `null` default
14+
status code to be passed to `Helpers::httpErrorStatus()` method.
15+
- [#518](https://github.com/cloudcreativity/laravel-json-api/issues/518)
16+
Ensure empty `sort` and `include` query parameters pass validation.
17+
518
## [2.0.0-beta.3] - 2020-04-13
619

720
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ A demo application is available at [here](https://github.com/cloudcreativity/dem
6262

6363
| Laravel | This Package |
6464
| --- | --- |
65-
| `^7.0` | `^2.0` (currently `beta` releases) |
65+
| `^7.0` | `^2.0` |
6666
| `^6.0` | `^1.7` |
6767
| `5.8.*` | `^1.7` |
6868
| `5.7.*` | `^1.0` |

docs/features/async.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Asynchronous Processing
22

3-
The JSON API specification
3+
The JSON API specification
44
[provides a recommendation](https://jsonapi.org/recommendations/#asynchronous-processing)
5-
for how APIs can implement long running processes. For example, if the operation to create a
6-
resource takes a long time, it is more appropriate to process the creation using
5+
for how APIs can implement long running processes. For example, if the operation to create a
6+
resource takes a long time, it is more appropriate to process the creation using
77
[Laravel's queue system](https://laravel.com/docs/queues)
88
and return a `202 Accepted` response to the client.
99

@@ -29,14 +29,14 @@ use Illuminate\Support\ServiceProvider;
2929

3030
class AppServiceProvider extends ServiceProvider
3131
{
32-
32+
3333
// ...
34-
34+
3535
public function register()
3636
{
3737
LaravelJsonApi::runMigrations();
3838
}
39-
39+
4040
}
4141
```
4242

@@ -45,7 +45,7 @@ class AppServiceProvider extends ServiceProvider
4545
If you want to customise the migrations, you can publish them as follows:
4646

4747
```bash
48-
$ php artisan vendor:publish --tag="json-api-migrations"
48+
$ php artisan vendor:publish --tag="json-api:migrations"
4949
```
5050

5151
If you do this, you **must not** call `LaravelJsonApi::runMigrations()` in your service provider.
@@ -76,7 +76,7 @@ use Neomerx\JsonApi\Schema\SchemaProvider;
7676
class Schema extends SchemaProvider
7777
{
7878
use AsyncSchema;
79-
79+
8080
// ...
8181
}
8282
```
@@ -112,7 +112,7 @@ class ProcessPodcast implements ShouldQueue
112112
{
113113

114114
use ClientDispatchable;
115-
115+
116116
// ...
117117
}
118118

@@ -130,7 +130,7 @@ means you can use any of the normal Laravel methods. The only difference is you
130130
`dispatch` method at the end of the chain so that you have access to the process that was stored
131131
and can be serialized into JSON by your API.
132132

133-
You can use this method of dispatching jobs in either
133+
You can use this method of dispatching jobs in either
134134
[Controller Hooks](../basics/controllers.md) or within
135135
[Resource Adapters](../basics/adapters.md), depending on your preference.
136136

@@ -190,9 +190,9 @@ class Adapter extends AbstractAdapter
190190
If a dispatched job creates a new resource (e.g. a new model), there is one additional step you will
191191
need to follow in the job's `handle` method. This is to link the stored process to the resource that was
192192
created as a result of the job completing successfully. The link must exist otherwise your API
193-
will not be able to inform a client of the location of the created resource once the job is complete.
193+
will not be able to inform a client of the location of the created resource once the job is complete.
194194

195-
You can easily create this link by calling the `didCreate` method that the `ClientDispatchable`
195+
You can easily create this link by calling the `didCreate` method that the `ClientDispatchable`
196196
trait adds to your job. For example:
197197

198198
```php
@@ -205,13 +205,13 @@ class ProcessPodcast implements ShouldQueue
205205
{
206206

207207
use ClientDispatchable;
208-
208+
209209
// ...
210-
210+
211211
public function handle()
212212
{
213213
// ...logic to process a podcast
214-
214+
215215
$this->didCreate($podcast);
216216
}
217217
}
@@ -272,11 +272,11 @@ This enables the following routes:
272272

273273
- `GET /podcasts/queue-jobs`: this lists all `queue-jobs` resources for the `podcasts`
274274
resource type.
275-
- `GET /podcasts/queue-jobs/<UUID>`: this retrieves a specific `queue-jobs` resource
275+
- `GET /podcasts/queue-jobs/<UUID>`: this retrieves a specific `queue-jobs` resource
276276
for the `podcasts` resource type.
277277

278278
The resource type `queue-jobs` is the name used in the JSON API's recommendation for
279-
asynchronous processing. If you want to use a resource type, then you can change this
279+
asynchronous processing. If you want to use a resource type, then you can change this
280280
by editing the `jobs.resource` config setting in your API's configuration file.
281281

282282
Note that we assume the resource id of a process is a valid UUID. If you use something
@@ -291,7 +291,7 @@ JsonApi::register('default')->withNamespace('Api')->routes(function ($api) {
291291
## HTTP Requests and Responses
292292

293293
Once you have followed the above instructions, you can now make HTTP requests and receive
294-
asynchronous process responses that following the
294+
asynchronous process responses that following the
295295
[JSON API recommendation.](https://jsonapi.org/recommendations/#asynchronous-processing)
296296

297297
For example, a request to create a podcast would receive the following response:

src/Api/Url.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,13 @@ public function replace(iterable $parameters): self
103103
$copy = clone $this;
104104

105105
foreach ($parameters as $key => $value) {
106-
$copy->namespace = \str_replace('{' . $key . '}', $value, $copy->namespace);
106+
$routeParamValue = $value;
107+
108+
if ($value instanceof UrlRoutable) {
109+
$routeParamValue = $value->getRouteKey();
110+
}
111+
112+
$copy->namespace = \str_replace('{' . $key . '}', $routeParamValue, $copy->namespace);
107113
}
108114

109115
return $copy;

src/Http/Responses/Responses.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ public function error($error, int $defaultStatusCode = null, array $headers = []
413413
* @param array $headers
414414
* @return mixed
415415
*/
416-
public function errors(iterable $errors, $defaultStatusCode = null, array $headers = [])
416+
public function errors(iterable $errors, int $defaultStatusCode = null, array $headers = [])
417417
{
418418
$errors = $this->factory->createErrors($errors);
419419
$statusCode = Helpers::httpErrorStatus($errors, $defaultStatusCode);

src/ServiceProvider.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ public function boot(Router $router)
8080

8181
$this->publishes([
8282
__DIR__ . '/../database/migrations' => database_path('migrations'),
83-
], 'json-api-migrations');
83+
], 'json-api:migrations');
84+
85+
$this->publishes([
86+
__DIR__ . '/../resources/lang' => resource_path('lang/vendor/jsonapi'),
87+
], 'json-api:translations');
8488

8589
$this->commands([
8690
Console\Commands\MakeAdapter::class,

src/Utils/Helpers.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,17 @@ public static function isJsonApi($request)
157157
* 4xx errors or 500 Internal Server Error might be appropriate for multiple 5xx errors.
158158
*
159159
* @param iterable|ErrorInterface $errors
160-
* @param int $default
160+
* @param int|null $default
161161
* @return int
162162
* @see https://jsonapi.org/format/#errors
163163
* @deprecated 3.0.0 use `Document\Error\Errors::getStatus()`
164164
*/
165-
public static function httpErrorStatus($errors, int $default = SymfonyResponse::HTTP_BAD_REQUEST): int
165+
public static function httpErrorStatus($errors, int $default = null): int
166166
{
167+
if (\is_null($default)) {
168+
$default = SymfonyResponse::HTTP_BAD_REQUEST;
169+
}
170+
167171
if ($errors instanceof ErrorInterface) {
168172
$errors = [$errors];
169173
}

src/Validation/AbstractValidators.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ protected function defaultQueryRules(): array
655655
],
656656
'include' => [
657657
'bail',
658+
'nullable',
658659
'string',
659660
$this->allowedIncludePaths(),
660661
],
@@ -665,6 +666,7 @@ protected function defaultQueryRules(): array
665666
],
666667
'sort' => [
667668
'bail',
669+
'nullable',
668670
'string',
669671
$this->allowedSortParameters(),
670672
],

tests/lib/Integration/Eloquent/ResourceTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ public function testSortedSearch()
6767
->assertFetchedManyInOrder([$b, $a]);
6868
}
6969

70+
public function testEmptySort(): void
71+
{
72+
$posts = factory(Post::class, 2)->create();
73+
74+
$this->jsonApi()
75+
->get('api/v1/posts?sort=')
76+
->assertFetchedMany($posts);
77+
}
78+
7079
public function testFilteredSearch()
7180
{
7281
$a = factory(Post::class)->create([
@@ -329,6 +338,18 @@ public function testReadWithInclude()
329338
->assertIsIncluded('tags', $tag);
330339
}
331340

341+
/**
342+
* @see https://github.com/cloudcreativity/laravel-json-api/issues/518
343+
*/
344+
public function testReadWithEmptyInclude(): void
345+
{
346+
$post = factory(Post::class)->create();
347+
348+
$this->jsonApi()
349+
->get("api/v1/posts/{$post->getRouteKey()}?include=")
350+
->assertFetchedOne($this->serialize($post));
351+
}
352+
332353
/**
333354
* @see https://github.com/cloudcreativity/laravel-json-api/issues/194
334355
*/

tests/lib/Integration/Routing/RouteParameterTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use CloudCreativity\LaravelJsonApi\Routing\RouteRegistrar;
2121
use CloudCreativity\LaravelJsonApi\Tests\Integration\TestCase;
2222
use DummyApp\Post;
23+
use DummyApp\User;
2324
use Illuminate\Support\Arr;
2425

2526
/**
@@ -77,4 +78,16 @@ public function testManual(): void
7778
Arr::get($data, 'data.links.self')
7879
);
7980
}
81+
82+
public function testModelBinding(): void
83+
{
84+
$post = factory(Post::class)->create();
85+
$user = factory(User::class)->create();
86+
$data = json_api(null, null, ['tenant' => $user])->encoder()->serializeData($post);
87+
88+
$this->assertSame(
89+
url('/foo/2/api/posts', $post),
90+
Arr::get($data, 'data.links.self')
91+
);
92+ }
8093
}

0 commit comments

Comments
 (0)
0