Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/json api output #24

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft

Feature/json api output #24

wants to merge 4 commits into from

Conversation

Nizari
Copy link
Collaborator

@Nizari Nizari commented Mar 2, 2020

@drtheuns het aantal commits is nu onduidelijk terug te zien door php cs fixer. Ik adviseer dat we die snel mergen ivm leesbaarheid. Benieuwd wat je voor de rest van me initiële opzet vindt!

@jorisatabix

@Nizari Nizari requested a review from drtheuns March 2, 2020 21:07
@Nizari Nizari self-assigned this Mar 2, 2020
@Nizari Nizari added the enhancement New feature or request label Mar 2, 2020
Copy link
Owner

@drtheuns drtheuns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the approach to have each resource be a separate object, but I feel like the current ResourceObject (in the commented out functions) is gaining a lot of responsibilities that feel like they belong to the renderer. Furthermore, we might not need things like a relationship object, as we already have Association.

Let's discuss how to move forward tomorrow.

phpstan.neon Outdated
@@ -10,3 +10,5 @@ parameters:
# This class does string-building with class-strings, which is more hassle
# to type-hint and annotate than it's worth.
- src/Apitizer/Support/ClassFilter.php

checkMissingIterableValueType: false
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not disable this, as it forces us to think about the content of our arrays/iterables, rather than having undocumented arrays with "something" in them. If the array is too complex to easily document, make it an object (or array of objects).

Comment on lines +37 to +39
if ($this->isSingleRowOfData($data)) {
$data = collect([$data]);
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems incorrect, as it makes it impossible to return a single object from the API, while that is supported by the JSON-API spec:

Primary data MUST be either:

  • a single resource object, a single resource identifier object, or null, for requests that target single resources
  • an array of resource objects, an array of resource identifier objects, or an empty array ([]), for requests that target resource collections

See https://jsonapi.org/format/#document-top-level

Comment on lines 47 to 56
$data = [
'data' => []
];

foreach ($this->resources as $resource) {
$data['data'][] = $resource->toArray();
}

return $data;
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably simplify this to something like:

return [
    'data' => collect($this->resources)->map->toArray()->all(),
];

If we add the Illuminate\Contracts\Support\Arrayable interface to the ResourceObject (which is already implemented with toArray), then we can simplify it even further to:

return [
    'data' => collect($this->resources)->toArray(),
];

Because the Collection class will then take care of calling toArray for us. This advice holds for all container objects we introduce by the way.

Comment on lines +21 to +25
// need to do this because DB unreliable since it doesn't always delete entire DB before test
$user = User::updateOrCreate(['id' => 1], [
'name' => 'Daan Hage',
'email' => '[email protected]',
]);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason a factory wasn't used for this?

Also, the database isn't deleted because the feature tests uses DatabaseTransactions to rollback changes, rather than completely rebuilding the database for all the tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Nizari It shouldn't be unreliable?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really possible when I return an ID. Need a way to keep ID the same every time

Copy link
Contributor

@jorisatabix jorisatabix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there so much uncommented code?

Haven't tested the code yet, just looked at it.

$request = $this->request()->fields('name, email')->make();
$result = UserBuilder::make($request)->setRenderer(new JsonApiRenderer)->render($collection);

$this->assertJsonStringEqualsJsonFile(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to assert on json? And maybe put it inline so we can directly see what the result should be.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but assertJsonStringEqualsJsonFile looks so hot!

Comment on lines +21 to +25
// need to do this because DB unreliable since it doesn't always delete entire DB before test
$user = User::updateOrCreate(['id' => 1], [
'name' => 'Daan Hage',
'email' => '[email protected]',
]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Nizari It shouldn't be unreliable?

class JsonApiTest extends TestCase
{
/** @test */
public function it_renders_existing_eloquent_model_to_jsonapi_format()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest
public function we_can_use_the_json_api_renderer_to_format_the_builder_response_in_json_api_format()

Mainly because I am looking at what this PR does from the tests. Same goes for the one below.

@@ -8,6 +8,9 @@
return [
'name' => $faker->name,
'email' => $faker->email,
'should_reset_password' => rand(0, 1),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use random in the factories. In another project, after using it for a while, it can lead to failures in x % of the time for certain tests.

It's probably not needed to be set here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? this value is always true or false so this should work. If a test is dependant on this value then it should be set inside the test and never be hidden inside factory

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thus it can be removed from here.

*/
public static function factory(array $attributes, string $type, string $id)
{
$resourceObject = new self($type, $id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the contstructor? Or factory(ResourceObject::class)->create($attributes);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

je can use the factory pattern also just for initing your object if you have some specific create logic you dont always want inside your constructor. I remember we had this discussion before ;)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't finish that discussion

@Nizari
Copy link
Collaborator Author

Nizari commented Mar 3, 2020

Why is there so much uncommented code?

Haven't tested the code yet, just looked at it.

Because I'm not done :). ANd its inspiration code

@codecov-io
Copy link

codecov-io commented Mar 13, 2020

Codecov Report

Merging #24 into master will decrease coverage by 0.23%.
The diff coverage is 76.92%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master      #24      +/-   ##
============================================
- Coverage     81.94%   81.71%   -0.24%     
- Complexity      851      875      +24     
============================================
  Files           105      108       +3     
  Lines          1983     2040      +57     
============================================
+ Hits           1625     1667      +42     
- Misses          358      373      +15     
Impacted Files Coverage Δ Complexity Δ
src/Apitizer/Rendering/JsonApiRenderer.php 57.14% <57.14%> (ø) 17.00 <17.00> (?)
src/Apitizer/JsonApi/Document.php 100.00% <100.00%> (ø) 3.00 <3.00> (?)
src/Apitizer/JsonApi/ResourceObject.php 100.00% <100.00%> (ø) 4.00 <4.00> (?)
src/Apitizer/Rendering/AbstractRenderer.php 100.00% <100.00%> (ø) 6.00 <2.00> (+2.00)
src/Apitizer/Rendering/BasicRenderer.php 100.00% <100.00%> (ø) 9.00 <3.00> (-2.00)
src/Apitizer/Types/AbstractField.php 100.00% <100.00%> (ø) 15.00 <2.00> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0685ce6...04e1fb0. Read the comment docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants