8000 [Feature] Allow host to not be included within encoded response · CodingSeo/laravel-json-api@3cf186d · GitHub
[go: up one dir, main page]

Skip to content

Commit 3cf186d

Browse files
committed
[Feature] Allow host to not be included within encoded response
1 parent e611610 commit 3cf186d

File tree

8 files changed

+312
-55
lines changed

8 files changed

+312
-55
lines changed

docs/api.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,14 @@ register routes for your API.
134134

135135
### Host
136136

137-
When processing inbound HTTP requests, the current server host will always be used when encoding JSON API documents.
137+
When processing inbound HTTP requests, the current server host will be used when encoding JSON API documents.
138138

139139
When encoding JSON API documents outside of HTTP requests, we use the `url.host` option from your API's configuration.
140140
If the value is `null`, we default to Laravel's `app.url` config setting. Otherwise, we'll use the value you've
141141
provided.
142142

143+
If you do not want the host to be appended to URLs in the encoded document, set `url.host` to `false`.
144+
143145
### Namespace
144146

145147
The URL namespace is the URL under which all resources for the API are nested. For example, if the namespace is

src/Api/Repository.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,16 @@ private function normalizeRootNamespace($namespace)
165165
*/
166166
private function normalizeUrl(array $url, $host = null)
167167
{
168+
$prependHost = false !== array_get($url, 'host');
169+
168170
if ($host) {
169171
$url['host'] = $host;
170-
}
171-
172-
if (!array_get($url, 'host')) {
172+
} elseif (!isset($url['host'])) {
173173
$url['host'] = $this->config->get('app.url');
174174
}
175175

176176
return new Url(
177-
(string) $url['host'],
177+
$prependHost ? (string) $url['host'] : '',
178178
(string) array_get($url, 'namespace'),
179179
(string) array_get($url, 'name')
180180
);

stubs/api.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
| detected from the inbound HTTP request. In other circumstances
6868
| (e.g. broadcasting), the host will be taken from the setting here.
6969
| If it is `null`, the `app.url` config setting is used as the default.
70+
| If you set `host` to `false`, the host will never be appended to URLs
71+
| for inbound requests.
7072
|
7173
| The name setting is the prefix for route names within this API.
7274
|

tests/Integration/BroadcastingTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,5 @@ public function testBroadcastWith()
1515

1616
$this->assertSame('posts', array_get($data, 'data.type'));
1717
$this->assertEquals($id = $post->getKey(), array_get($data, 'data.id'));
18-
$this->assertEquals("http://localhost/api/v1/posts/$id", array_get($data, 'data.links.self'));
1918
}
2019
}

tests/Integration/Eloquent/PostsTest.php

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -94,36 +94,9 @@ public function testCreate()
9494
public function testRead()
9595
{
9696
$model = $this->createPost();
97-
/** @var Tag $tag */
98-
$tag = $model->tags()->create(['name' => 'Important']);
99-
100-
$data = [
101-
'type' => 'posts',
102-
'id' => (string) $model->getKey(),
103-
'attributes' => [
104-
'title' => $model->title,
105-
'slug' => $model->slug,
106-
'content' => $model->content,
107-
],
108-
'relationships' => [
109-
'author' => [
110-
'data' => [
111-
'type' => 'users',
112-
'id' => (string) $model->author_id,
113-
],
114-
],
115-
'tags' => [
116-
'data' => [
117-
[
118-
'type' => 'tags',
119-
'id' => (string) $tag->getKey(),
120-
],
121-
],
122-
],
123-
],
124-
];
97+
$model->tags()->create(['name' => 'Important']);;
12598

126-
$this->doRead($model)->assertReadResponse($data);
99+
$this->doRead($model)->assertReadResponse($this->serialize($model));
127100
}
128101

129102
/**
@@ -169,4 +142,42 @@ private function createPost($create = true)
169142

170143
return $create ? $builder->create() : $builder->make();
171144
}
145+
146+
/**
147+
* Get the posts resource that we expect in server responses.
148+
*
149+
* @param Post $model
150+
* @return array
151+
*/
152+
private function serialize(Post $model)
153+
{
154+
return [
155+
'type' => 'posts',
156+
'id' => $id = (string) $model->getKey(),
157+
'attributes' => [
158+
'title' => $model->title,
159+
'slug' => $model->slug,
160+
'content' => $model->content,
161+
],
162+
'relationships' => [
163+
'author' => [
164+
'data' => [
165+
'type' => 'users',
166+
'id' => (string) $model->author_id,
167+
],
168+
],
169+
'tags' => [
170+
'data' => $model->tags->map(function (Tag $tag) {
171+
return ['type' => 'tags', 'id' => (string) $tag->getKey()];
172+
})->all(),
173+
],
174+
'comments' => [
175+
'links' => [
176+
'self' => "http://localhost/api/v1/posts/$id/relationships/comments",
177+
'related' => "http://localhost/api/v1/posts/$id/comments",
178+
],
179+
],
180+
],
181+
];
182+
}
172183
}

tests/Integration/EncodingTest.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
namespace CloudCreativity\LaravelJsonApi\Tests\Integration;
4+
5+
use CloudCreativity\LaravelJsonApi\Routing\ApiGroup;
6+
use CloudCreativity\LaravelJsonApi\Tests\Models\Post;
7+
8+
class EncodingTest extends TestCase
9+
{
10+
11+
/**
12+
* If the URL host is set to `null`, we expect the request host to be prepended to links.
13+
*/
14+
public function testRequestedResourceHasRequestHost()
15+
{
16+
$id = factory(Post::class)->create()->getKey();
17+
config()->set('json-api-default.url.host', null);
18+
19+
$json = $this
20+
->withApiRoutes()
21+
->getJsonApi("http://www.example.com/api/v1/posts/$id")
22+
->json();
23+
24+
$this->assertLinks('http://www.example.com', $id, $json);
25+
}
26+
27+
/**
28+
* If the URL host is set to `false`, we do not expect a host to be prepended to links.
29+
*/
30+
public function testRequestedResourceDoesNotHaveHost()
31+
{
32+
$id = factory(Post::class)->create()->getKey();
33+
config()->set('json-api-default.url.host', false);
34+
35+
$json = $this
36+
->withApiRoutes()
37+
->getJsonApi("http://www.example.com/api/v1/posts/$id")
38+
->json();
39+
40+
$this->assertLinks('', $id, $json);
41+
}
42+
43+
/**
44+
* When encoding outside of a request and the URL host is set to `null`, we expect the
45+
* `app.url` config setting to be used.
46+
*/
47+
public function testSerializedResourceHasAppHost()
48+
{
49+
$post = factory(Post::class)->create();
50+
51+
config()->set('app.url', $host = 'http://www.example.com');
52+
config()->set('json-api-default.url.host', null);
53+
54+
$json = json_api('default')->encoder()->serializeData($post);
55+
$this->assertLinks($host, $post->getKey(), $json);
56+
}
57+
58+
/**
59+
* When encoding outside of a request and the URL host is set to a specified host,
60+
* we expect that to be used.
61+
*/
62+
public function testSerializedResourceHasSpecificHost()
63+
{
64+
$post = factory(Post::class)->create();
65+
66+
config()->set('app.url', 'http://localhost');
67+
config()->set('json-api-default.url.host', $host = 'http://www.example.com');
68+
69+
$json = json_api('default')->encoder()->serializeData($post);
70+
$this->assertLinks($host, $post->getKey(), $json);
71+
}
72+
73+
/**
74+
* When encoding outside of a request and the URL host is set to `false`, we expect
75+
* no host in the serialized data.
76+
*/
77+
public function testSerializedResourceDoesNotHaveAppHost()
78+
{
79+
$post = factory(Post::class)->create();
80+
81+
config()->set('app.url', 'http://www.example.com');
82+
config()->set('json-api-default.url.host', false);
83+
84+
$json = json_api('default')->encoder()->serializeData($post);
85+
$this->assertLinks('', $post->getKey(), $json);
86+
}
87+
88+
/**
89+
* @param $host
90+
* @param $id
91+
* @param array $json
92+
*/
93+
private function assertLinks($host, $id, array $json)
94+
{
95+
$this->assertArraySubset([
96+
'data' => [
97+
'links' => [
98+
'self' => "$host/api/v1/posts/$id",
99+
],
100+
],
101+
], $json);
102+
}
103+
104+
/**
105+
* @return $this
106+
*/
107+
private function withApiRoutes()
108+
{
109+
$this->withDefaultApi([], function (ApiGroup $api) {
110+
$api->resource('posts');
111+
});
112+
113+
return $this;
114+
}
115+
}

0 commit comments

Comments
 (0)
0