You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+10-5Lines changed: 10 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,15 +20,20 @@ This section covers usage examples and a detailed explanation of library element
20
20
- - -
21
21
_Before we proceed, here are a few notes:_
22
22
*_Namespaces for Article and Comment are just for demo purposes. You can place it wherever you want._
23
-
*_We use `readonly` for properties because we don't want that value assigned during the creation of the object is changed, but you don't need to do this. If using a version of PHP prior 8.1 you can add `@psalm-immutable` annotation on the class to have readonly behaviour for properties._
23
+
*_We use `readonly` for properties because we don't want that value assigned during the creation of the object is changed, but you don't need to do this. If using a version of PHP prior 8.1 you can add `@psalm-immutable`(read more about Psalm [here](https://github.com/vimeo/psalm)) annotation on the class to have readonly behaviour for properties._
24
24
*_Final class is used on the class because we don't want to extend read models, but if you need to extend it remove final declaration (although we recommend to have one read model per resource which only implements ApiModel and doesn't extend any other model)._
25
25
*_Given examples have a lot of logic inside the controller because of readability. In a real application, we would recommend splitting the logic and move it into separate classes._
26
26
*_Given examples have parameters from query passed into query bus, which should return an array of results. Instead of using the query bus, you can inject the repository and send parameters directly to it or even inject a database connection and make a raw query with the given parameters. Use whatever approach you use when building your applications._
27
27
- - -
28
28
29
29
### <aname='return-response'></a>How to return the JSON:API compliant response?
30
30
31
-
To return JSON:API compliant response, you have to go through a couple of steps - what you need is read or write side and responder. Both read and write sides logically consist of several classes - the controller, an entry point of the request, the model used to create the entity or return requested information, and the entity that stores the data. Responder serves as a glue, mapping the entities to models.
31
+
To return JSON:API compliant response, you have to go through a couple of steps - what you need is read or write side and responder. Both read and write sides logically consist of several classes:
32
+
* the controller, an entry point of the request
33
+
* the model used to create the entity or return requested information
34
+
* the entity that stores the data
35
+
36
+
Responder serves as a glue, mapping the entities to models.
32
37
33
38
Before going deeper into the read and write models, responders and controllers, it's a good idea to describe how we distinguish attributes from relations in our models. To recognise which property is attribute and which one is relation we use annotations. Each model should have one "main" annotation that determines its type, a top-level member for any resource object. This annotation is placed just above the class declaration, and it looks like this:
34
39
@@ -51,7 +56,7 @@ Apart from `@ResourceType` annotation, there are three more - `@Attribute`, `@To
51
56
public readonly array $commentIds,
52
57
```
53
58
54
-
**Name** value is what we want to show in response. For this example, `article_comments` is the name for this relationship that will be returned in the response.\
59
+
**Name** value is what we want to show in response. For this example, `article_comments` is the name for this relationship that will be returned in the response. If no name is defined in the annotation the relationship will inherit the property name.\
55
60
**Type** value is the resource type of relation to which we're referring. Here, we're referring to comments, meaning that a model of type comments related to this model is part of the codebase. Keep in mind that the library links only types of the exact name, so if your model is of type `comment`, and you make a mistake and write plural library will throw an error.
56
61
57
62
Relationships can be nullable, and to add a nullable relationship to the model, you just need to assign a bool value to `nullable` property inside the annotation, like in the following example. Don't forget to null safe type-hint your property in that case, and remember - relationships are not nullable by default.
@@ -474,7 +479,7 @@ class Controller
474
479
}
475
480
```
476
481
477
-
Whether the client requested explicitly requested includes, or the response needs to have all the possible includes, Responder needs to have the mapping for the read model of each entity that is returned in the response.
482
+
Whether the client requested explicitly requested includes, or the response needs to have all the possible includes, Responder needs to have the mapping for the read model of each object that is returned in the response.
478
483
479
484
When returning includes inside a list of objects (e.g. returning a list of articles from the `/articles` endpoint) there is a chance that different resources will have same relations. In that case we want to include the relation only once. E.g., if we have a list of articles and some articles have the same author, we want to include that author only once. We can use [\Undabot\SymfonyJsonApi\Model\Collection\UniqueCollection](src/Model/Collection/ObjectCollection.php#L11) for that.
480
485
@@ -571,7 +576,7 @@ class Controller
571
576
572
577
#### Pagination
573
578
574
-
The library can currently read page and offset based pagination. So no matter which one the client sends to the server, we can read them both like in the example below.
579
+
The library can currently read page and offset based pagination. Page based pagination is automatically converted to an offset based pagination. So no matter which one the client sends to the server, we can read them both like in the example below.
0 commit comments