Skip to content

Commit 4955171

Browse files
meyerbaptistedunglas
authored andcommitted
Elasticsearch documentation (#717)
* Elasticsearch documentation * CS
1 parent 4a6e7e8 commit 4955171

23 files changed

+586
-72
lines changed

core/configuration.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ api_platform:
9090
graphiql:
9191
enabled: true
9292

93+
elasticsearch:
94+
# To enable or disable Elasticsearch support.
95+
enabled: false
96+
97+
# The hosts to the Elasticsearch nodes.
98+
hosts: []
99+
100+
# The mapping between resource classes and indexes.
101+
mapping: []
102+
93103
swagger:
94104
# The swagger api keys.
95105
api_keys: []

core/data-providers.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Data Providers
22

33
To retrieve data exposed by the API, API Platform uses classes called **data providers**. A data provider using [Doctrine
4-
ORM](http://www.doctrine-project.org/projects/orm.html) to retrieve data from a database is included with the library and
5-
is enabled by default. This data provider natively supports paged collections and filters. It can be used as is and fits
6-
perfectly with common usages.
4+
ORM](http://www.doctrine-project.org/projects/orm.html) to retrieve data from a database, a data provider using
5+
[Doctrine MongoDB ODM](https://www.doctrine-project.org/projects/mongodb-odm.html) to retrieve data from a document
6+
database, and a data provider using [Elasticsearch-PHP](https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html)
7+
to retrieve data from an Elasticsearch cluster are included with the library. The first one is enabled by default. These
8+
data providers natively support paged collections and filters. They can be used as is and fits perfectly with common usages.
79

8-
However, you sometime want to retrieve data from other sources such as another persistence layer, a webservice, ElasticSearch
9-
or MongoDB.
10+
However, you sometime want to retrieve data from other sources such as another persistence layer or a webservice.
1011
Custom data providers can be used to do so. A project can include as many data providers as it needs. The first able to
1112
retrieve data for a given resource will be used.
1213

core/default-order.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class Book
2424
* ...
2525
*/
2626
public $foo;
27+
28+
// ...
2729
}
2830
```
2931

@@ -54,6 +56,8 @@ class Book
5456
* ...
5557
*/
5658
public $bar;
59+
60+
// ...
5761
}
5862
```
5963

@@ -78,5 +82,7 @@ class Book
7882
* @var User
7983
*/
8084
public $author;
85+
86+
// ...
8187
}
8288
```

core/deprecations.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class Review
9393
* @ApiProperty(deprecationReason="Use the rating property instead")
9494
*/
9595
public $letter;
96+
97+
// ...
9698
}
9799
```
98100

core/elasticsearch.md

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
# Elasticsearch Support
2+
3+
## Overview
4+
5+
Elasticsearch is a distributed, RESTful search and analytics engine capable of solving a growing number of use cases:
6+
application search, security analytics, metrics, logging, etc.
7+
8+
API Platform comes natively with the **reading** support for Elasticsearch. It uses internally the official PHP client
9+
for Elasticsearch: [Elasticsearch-PHP](https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html).
10+
11+
Be careful, API Platform only supports Elasticsearch >= 6.5.0.
12+
13+
## Enabling reading support
14+
15+
To enable the reading support for Elasticsearch, simply require the Elasticsearch-PHP package using Composer:
16+
17+
$ composer require elasticsearch/elasticsearch:^6.0
18+
19+
Then, enable it inside the API Platform configuration:
20+
21+
```yaml
22+
# api/config/packages/api_platform.yaml
23+
parameters:
24+
# ...
25+
env(ELASTICSEARCH_HOST): 'http://localhost:9200'
26+
27+
api_platform:
28+
# ...
29+
30+
mapping:
31+
paths: ['%kernel.project_dir%/src/Model']
32+
33+
elasticsearch:
34+
hosts: ['%env(ELASTICSEARCH_HOST)%']
35+
36+
#...
37+
```
38+
39+
## Creating models
40+
41+
First of all, API Platform follows the best practices of Elasticsearch:
42+
* a single index per resource should be used because Elasticsearch is going to [drop support for index types and will allow only a single type per
43+
index](https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html);
44+
* index name should be the short resource name in lower case;
45+
* the default `_doc` type should be used;
46+
* all fields should be lower case and should use snake case for combining words.
47+
48+
This involves having mappings and models which absolutely match each other.
49+
50+
Here is an example of mappings for 2 resources, `User` and `Tweet`, and their models:
51+
52+
```json
53+
PUT user
54+
{
55+
"mappings": {
56+
"_doc": {
57+
"properties": {
58+
"id": {
59+
"type": "keyword"
60+
},
61+
"gender": {
62+
"type": "keyword"
63+
},
64+
"age": {
65+
"type": "integer"
66+
},
67+
"first_name": {
68+
"type": "text"
69+
},
70+
"last_name": {
71+
"type": "text"
72+
},
73+
"tweets": {
74+
"type": "nested",
75+
"properties": {
76+
"id": {
77+
"type": "keyword"
78+
},
79+
"date": {
80+
"type": "date",
81+
"format": "yyyy-MM-dd HH:mm:ss"
82+
},
83+
"message": {
84+
"type": "text"
85+
}
86+
},
87+
"dynamic": "strict"
88+
}
89+
},
90+
"dynamic": "strict"
91+
}
92+
}
93+
}
94+
```
95+
96+
```json
97+
PUT tweet
98+
{
99+
"mappings": {
100+
"_doc": {
101+
"properties": {
102+
"id": {
103+
"type": "keyword"
104+
},
105+
"author": {
106+
"properties": {
107+
"id": {
108+
"type": "keyword"
109+
},
110+
"gender": {
111+
"type": "keyword"
112+
},
113+
"age": {
114+
"type": "integer"
115+
},
116+
"first_name": {
117+
"type": "text"
118+
},
119+
"last_name": {
120+
"type": "text"
121+
}
122+
},
123+
"dynamic": "strict"
124+
},
125+
"date": {
126+
"type": "date",
127+
"format": "yyyy-MM-dd HH:mm:ss"
128+
},
129+
"message": {
130+
"type": "text"
131+
}
132+
},
133+
"dynamic": "strict"
134+
}
135+
}
136+
}
137+
```
138+
139+
```php
140+
<?php
141+
// api/src/Model/User.php
142+
143+
namespace App\Model;
144+
145+
use ApiPlatform\Core\Annotation\ApiProperty;
146+
use ApiPlatform\Core\Annotation\ApiResource;
147+
148+
/**
149+
* @ApiResource
150+
*/
151+
class User
152+
{
153+
/**
154+
* @ApiProperty(identifier=true)
155+
*
156+
* @var string
157+
*/
158+
public $id;
159+
160+
/**
161+
* @var string
162+
*/
163+
public $gender;
164+
165+
/**
166+
* @var int
167+
*/
168+
public $age;
169+
170+
/**
171+
* @var string
172+
*/
173+
public $firstName;
174+
175+
/**
176+
* @var string
177+
*/
178+
public $lastName;
179+
180+
/**
181+
* @var Tweet[]
182+
*/
183+
public $tweets = [];
184+
}
185+
```
186+
187+
```php
188+
<?php
189+
// api/src/Model/Tweet.php
190+
191+
namespace App\Model;
192+
193+
use ApiPlatform\Core\Annotation\ApiProperty;
194+
use ApiPlatform\Core\Annotation\ApiResource;
195+
196+
/**
197+
* @ApiResource
198+
*/
199+
class Tweet
200+
{
201+
/**
202+
* @ApiProperty(identifier=true)
203+
*
204+
* @var string
205+
*/
206+
public $id;
207+
208+
/**
209+
* @var User
210+
*/
211+
public $author;
212+
213+
/**
214+
* @var \DateTimeInterface
215+
*/
216+
public $date;
217+
218+
/**
219+
* @var string
220+
*/
221+
public $message;
222+
}
223+
```
224+
225+
API Platform will automatically disable write operations and snake case document fields will automatically be converted to
226+
camel case object properties during serialization.
227+
228+
Keep in mind that it is your responsibility to populate your Elasticsearch index. To do so, you can use [Logstash](https://www.elastic.co/products/logstash),
229+
a custom [data persister](data-persisters.md#creating-a-custom-data-persister) or any other mechanism that fits for your
230+
project (such as an [ETL](https://en.wikipedia.org/wiki/Extract,_transform,_load)).
231+
232+
You're done! The API is now ready to use.
233+
234+
### Creating custom mapping
235+
236+
If you don't follow the Elasticsearch recommendations, you may want a custom mapping between API Platform resources and
237+
Elasticsearch indexes/types.
238+
239+
For example, consider an index being similar to a database in an SQL database and a type being equivalent to a table.
240+
So the `User` and `Tweet` resources of the previous example would become `user` and `tweet` types in an index named `app`:
241+
242+
```yaml
243+
# api/config/packages/api_platform.yaml
244+
parameters:
245+
# ...
246+
env(ELASTICSEARCH_HOST): 'http://localhost:9200'
247+
248+
api_platform:
249+
# ...
250+
251+
mapping:
252+
paths: ['%kernel.project_dir%/src/Model']
253+
254+
elasticsearch:
255+
hosts: ['%env(ELASTICSEARCH_HOST)%']
256+
mapping:
257+
App\Model\User:
258+
index: app
259+
type: user
260+
App\Model\Tweet:
261+
index: app
262+
type: tweet
263+
264+
#...
265+
```
266+
267+
## Filtering
268+
269+
See how to use Elasticsearch filters and how to create Elasticsearch custom filters in [the Filters chapter](filters.md).
270+
271+
## Creating custom extensions
272+
273+
See how to create Elasticsearch custom extensions in [the Extensions chapter](extensions.md).

core/errors.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ configure API Platform to convert it to a `404 Not Found` error:
1515

1616
```php
1717
<?php
18-
// src/Exception/ProductNotFoundException.php
18+
// api/src/Exception/ProductNotFoundException.php
1919

2020
namespace App\Exception;
2121

@@ -26,7 +26,7 @@ final class ProductNotFoundException extends \Exception
2626

2727
```php
2828
<?php
29-
// src/EventSubscriber/CartManager.php
29+
// api/src/EventSubscriber/CartManager.php
3030

3131
namespace App\EventSubscriber;
3232

core/extending-jsonld-context.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class Book
3737
* )
3838
*/
3939
public $name;
40+
41+
// ...
4042
}
4143
```
4244

0 commit comments

Comments
 (0)