|
1 | 1 | # General Design Considerations
|
2 | 2 |
|
3 |
| -API Platform can be used [both as a "design-first" and "code-first"](https://swagger.io/blog/api-design/design-first-or-code-first-api-development/) |
4 |
| -API framework. However, the "design-first" approach is recommended: first you design the **public** shape of API endpoints. |
5 |
| - |
6 |
| -To do so, you write a plain old PHP object representing the input and output of your endpoint. This is the class that will |
7 |
| -be marked with the `@ApiResource` annotation. |
8 |
| -This class **doesn't have** to be mapped with Doctrine, or any other persistence system. It must be simple (usually just |
9 |
| -a data structure with no or minimal behaviors) and will be automatically to converted to [Hydra](extending-jsonld-context.md), |
10 |
| -[OpenAPI / Swagger](swagger.md) and [GraphQL](graphql.md) documentations by API Platform (there is a 1-1 mapping between |
11 |
| -this object and those docs). |
12 |
| - |
13 |
| -Then, it's up to the developer to feed API Platform with an hydrated version of this API resource object by implementing |
| 3 | +Because to create a working web API you only need to describe the structure of data to expose, API Platform is both [a "design-first" |
| 4 | +and "code-first"](https://swagger.io/blog/api-design/design-first-or-code-first-api-development/) API framework. |
| 5 | +However, the "design-first" methodology is strongly recommended: first you design the **public shape** of API endpoints. |
| 6 | + |
| 7 | +To do so, you have to write a plain old PHP object representing the input and output of your endpoint. This is the class |
| 8 | +that is [marked with the `@ApiResource` annotation](../distribution/index.md). |
| 9 | +This class **doesn't have** to be mapped with Doctrine ORM, or any other persistence system. It must be simple (it's usually |
| 10 | +just a data structure with no or minimal behaviors) and will be automatically converted to [Hydra](extending-jsonld-context.md), |
| 11 | +[OpenAPI / Swagger](swagger.md) and [GraphQL](graphql.md) documentations or schemas by API Platform (there is a 1-1 mapping |
| 12 | +between this class and those docs). |
| 13 | + |
| 14 | +Then, it's up to the developer to feed API Platform with an hydrated instance of this API resource object by implementing |
14 | 15 | the [`DataProviderInterface`](data-providers.md). Basically, the data provider will query the persistence system (RDBMS,
|
15 | 16 | document or graph DB, external API...), and must hydrate and return the POPO that has been designed in the first time.
|
16 | 17 |
|
17 | 18 | When updating a state (`POST`, `PUT`, `PATCH`, `DELETE` HTTP methods), it's up to the developer to persist properly the
|
18 |
| -data provided by API Platform's resource object hydrated by the serializer to the persistence system. To do so, there is |
19 |
| -another interface to implement: [`DataPersisterInterface`](data-persisters.md). Here, is the reverse operation, this class |
20 |
| -will read the API Platform resource object, hydrate a DTO and trigger a command, populate and event store, or persist the |
21 |
| -data in any other useful way (it's not the responsibility of API Platform, it's up to the application developer). |
| 19 | +data provided by API Platform's resource object [hydrated by the serializer](serialization.md) to the persistence system. |
| 20 | +To do so, there is another interface to implement: [`DataPersisterInterface`](data-persisters.md). |
| 21 | + |
| 22 | +Here is the reverse operation, this class will read the API resource object (the one marked with `@ApiResource`) and: |
| 23 | + |
| 24 | +* persist it directly in the database; |
| 25 | +* or hydrate a DTO then trigger a command; |
| 26 | +* or populate an event store; |
| 27 | +* or persist the data in any other useful way. |
| 28 | + |
| 29 | +The logic to execute in data persisters is the responsibility of application developers, and is **out of the API Platform's |
| 30 | +scope**. |
22 | 31 |
|
23 | 32 | For [Rapid Application Development](https://en.wikipedia.org/wiki/Rapid_application_development), convenience and prototyping,
|
24 |
| -**if and only if the class is marked with `@ApiResource` is also a Doctrine entity**, the developer can use the Doctrine |
25 |
| -ORM's data provider and data persister implementations shipped with API Platform. |
| 33 | +**if and only if the class marked with `@ApiResource` is also a Doctrine entity**, the developer can use the Doctrine |
| 34 | +ORM's data provider and persister implementations shipped with API Platform. |
26 | 35 |
|
27 | 36 | In this case, the public (`@ApiResource`) and internal (Doctrine entity) data model are shared. Then, API Platform will
|
28 | 37 | be able to query, filter, paginate and persist automatically data.
|
29 | 38 | This is approach is super-convenient and efficient, but is probably **not a good idea** for non-[CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete)
|
30 | 39 | and/or large systems.
|
31 |
| -It's up to the developers to use, or to not use those built-in data providers/persisters depending of the business they |
32 |
| -are dealing with. API Platform makes it easy to create custom data providers and persisters, and to implement appropriate patterns such as |
33 |
| -[CQS](https://www.martinfowler.com/bliki/CommandQuerySeparation.html) or [CQRS](https://martinfowler.com/bliki/CQRS.html). |
| 40 | +Again, it's up to the developers to use, or to not use those built-in data providers/persisters depending of the business |
| 41 | +they are dealing with. API Platform makes it easy to create custom data providers and persisters, and to implement appropriate |
| 42 | +patterns such as [CQS](https://www.martinfowler.com/bliki/CommandQuerySeparation.html) or [CQRS](https://martinfowler.com/bliki/CQRS.html). |
34 | 43 |
|
35 |
| -To create [Event Sourcing](https://martinfowler.com/eaaDev/EventSourcing.html)-based systems, a convenient approach is: |
| 44 | +Last but not least, to create [Event Sourcing](https://martinfowler.com/eaaDev/EventSourcing.html)-based systems, a convenient |
| 45 | +approach is: |
36 | 46 |
|
37 | 47 | * to persist data in an event store using a custom [data persister](data-persisters.md)
|
38 | 48 | * to create projections in standard RDBMS (Postgres, MariaDB...) tables or views
|
|
0 commit comments