Skip to content

Commit e715256

Browse files
authored
TypedAPI: First version of documentation (#509)
* Add documentation
1 parent ec99aad commit e715256

16 files changed

+386
-0
lines changed

.doc/index.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ include::overview.asciidoc[]
99
include::installation.asciidoc[]
1010

1111
include::connecting.asciidoc[]
12+
13+
include::typedapi/index.asciidoc[]
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
[[endpoints]]
2+
==== Endpoints
3+
4+
All the available endpoints are generated in separate packages and assembled in the client. The `core` namespace is duplicated at the root of the client for convenient access.
5+
6+
Each endpoint follows a factory pattern which returns a pointer to a new instance each time. This leads to a builder pattern allowing to directly chain the options before running your query.
7+
8+
[source,go]
9+
-----
10+
res, err := es.Search().Index("index_name").AllowPartialSearchResults(true).Do(context.Background())
11+
-----
12+
13+
If parameters are needed for the specific endpoint you are using, those will be present as arguments in the same order as the API:
14+
15+
[source,go]
16+
------------------------------------
17+
es.Create("index_name", "doc_id").Do(context.Background())
18+
------------------------------------
19+
20+
Otherwise, you can find them within the builder:
21+
22+
[source,go]
23+
------------------------------------
24+
es.Search().Index("index_name").Do(context.Background())
25+
------------------------------------
26+
27+
Alternatively each endpoint can be instantiated directly from its package:
28+
29+
[source,go]
30+
------------------------------------
31+
transport, err := elastictransport.New(elastictransport.Config{})
32+
res, err = search.New(transport).Do(context.Background())
33+
------------------------------------
34+
35+
The `Do` method takes an optional `context`, runs the request through the transport and returns the results as well as an error.
36+
37+
For body-empty endpoints such as `core.Exists`, an additional method `IsSuccess` is available. As the `Do` method, it takes an optional `context`, drains and closes the body if needed, and returns a boolean alongside an error
38+
39+
[source,go]
40+
-----
41+
if exists, err := es.Core.Exists("index_name", "doc_id").IsSuccess(context.Background()); exists {
42+
// The document exists!
43+
} else if err != nil {
44+
// An error occurred.
45+
}
46+
-----
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[[conventions]]
2+
=== Conventions
3+
4+
This section details the conventions upon which the typed client is built.
5+
6+
* <<structure>>
7+
* <<naming>>
8+
* <<endpoints>>
9+
* <<requests>>
10+
* <<responses>>
11+
* <<types>>
12+
13+
include::structure.asciidoc[]
14+
include::naming.asciidoc[]
15+
include::endpoints.asciidoc[]
16+
include::requests.asciidoc[]
17+
include::responses.asciidoc[]
18+
include::types.asciidoc[]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[[naming]]
2+
==== Naming
3+
4+
Whenever appropriate, names may be suffixed with an underscore:
5+
6+
* To avoid collision with protected keywords (`range, `if`, `type`, and so on).
7+
* To reflect the presence of a leading underscore in the API like `\_index` vs `Index_` or `\_source` vs `Source_`.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[[requests]]
2+
==== Requests
3+
4+
Requests are modeled around structures that follows as closely as possible the {es} API and uses the standard `json/encoding` for serialization.
5+
Corresponding request can be found withing the same package as its endpoint and comes with a Builder that allows you to deep dive into the API by following the types.
6+
7+
The builder is particularly useful around pointer fields and is embeddable within a standard struct declaration, such that these two declarations give you the same result:
8+
9+
[source,go]
10+
------------------------------------
11+
types.QueryContainer{
12+
Term: map[types.Field]types.TermQuery{
13+
"name": {Value: "Foo"},
14+
},
15+
}
16+
types.QueryContainer{
17+
Term: map[types.Field]types.TermQuery{
18+
"name": types.NewTermQueryBuilder().Value(types.NewFieldValueBuilder().String("Foo")).Build(),
19+
},
20+
}
21+
------------------------------------
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[[responses]]
2+
==== Responses
3+
4+
While not part of the initial release responses will be added at a later date.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[[structure]]
2+
==== Structure
3+
4+
The Typed client lives in the `typedapi` package within the `go-elasticsearch` repository.
5+
6+
The entire client is summed in an index at the root of the package for convenient access after instantiation.
7+
8+
Each endpoint resides in its own package within `typedapi` and contains the client for this endpoint, the `Request` struct along with its builder, if applicable.
9+
10+
The requests are based on a collection of structures generated from the https://github.com/elastic/elasticsearch-specification[elasticsearch-specification] repository and gathered in a `types` package within `typedapi`.
11+
Each type comes with a fluent builder for convenient creation and discoverability.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[[types]]
2+
==== Types
3+
4+
Requests and responses are relying on a collection of structures generated from the https://github.com/elastic/elasticsearch-specification[elasticsearch-specification] in the `types` package.
5+
Each type comes with json tags and a builder.
6+
7+
==== Enums
8+
9+
The {es} API has several instances of enumerations, each has a package within `types/enums`.
10+
An enum is declared as a type and each member of the enum is an exported variable with its value.
11+
The enum types serializes to the relevant API value, for example the `refresh` options which can be found in the Search API:
12+
13+
[source,go]
14+
------------------------------------
15+
refresh.True => "true"
16+
refresh.False => "false"
17+
refresh.Waitfor => "wait_for"
18+
------------------------------------
19+
20+
==== Unions
21+
22+
To capture the expressiveness of the API union fields are represented by a type alias to an interface.
23+
Each type alias comes with a builder that lists the possible types for the underlying value.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[[aggregations]]
2+
==== Aggregations
3+
4+
Given documents with a `price` field, we run a sum aggregation on `index_name`:
5+
[source,go]
6+
-----
7+
totalPricesAgg, err := es.Search().
8+
Index("index_name"). // <1>
9+
Request(
10+
search.NewRequestBuilder().
11+
Size(0). // <2>
12+
Aggregations(
13+
map[string]*types.AggregationContainerBuilder{
14+
"total_prices": types.NewAggregationContainerBuilder(). // <3>
15+
Sum(types.NewSumAggregationBuilder().Field("price")), // <4>
16+
}).
17+
Build(),
18+
).Do(context.Background())
19+
-----
20+
<1> Specifies the index name.
21+
<2> Sets the size to 0 to retrieve only the result of the aggregation.
22+
<3> Specifies the field name on which the sum aggregation runs.
23+
<4> The `SumAggregation` is part of the `AggregationContainer` map.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[[retrieving_document]]
2+
==== Retrieving a document
3+
4+
Retrieving a document follows the API as part of the argument of the endpoint.
5+
In order you provide the `index`, the `id` and then run the query:
6+
[source,go]
7+
-----
8+
res, err := es.Get("index_name", "doc_id").Do(context.Background())
9+
-----
10+
11+
==== Checking for a document existence
12+
13+
If you do not wish to retrieve the content of the document and want only to check if it exists in your index, we provide the `IsSuccess` shortcut:
14+
[source,go]
15+
-----
16+
if exists, err := es.Exists("index_name", "doc_id").IsSuccess(nil); exists {
17+
// The document exists !
18+
} else if err != nil {
19+
// Handle error.
20+
}
21+
-----
22+
23+
Result is `true` if everything succeeds, `false` if the document doesn't exist.
24+
If an error occurs during the request, you will be granted with a `false` and the relevant error.

0 commit comments

Comments
 (0)