Skip to content

Commit 09f5475

Browse files
committed
Improve codec architecture documentation
1 parent 86a68e1 commit 09f5475

File tree

1 file changed

+24
-65
lines changed

1 file changed

+24
-65
lines changed

src/Codec/architecture.md

Lines changed: 24 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -8,76 +8,36 @@ for a more flexible and efficient way to handle BSON data.
88

99
## Encoders and Decoders
1010

11-
The codec interface is comprised by two smaller interfaces: encoders and decoders. Both interfaces are marked as
12-
internal, as users are only expected to interact with the Codec interface. The interfaces are typed as generics through
13-
`@template` annotations, allowing for better type checking when they are used. Without type annotations, the interfaces
14-
are equivalent to the following:
11+
The `Codec` interface is comprised of two smaller interfaces: `Decoder` and `Encoder`. The interfaces are typed as
12+
generics through `@template` annotations, allowing for better type checking when they are used.
1513

16-
```php
17-
namespace MongoDB\Codec;
14+
Each decoder and encoder may support a limited set of types or even values. Before calling `decode` or `encode`, the
15+
`canDecode` and `canEncode` methods can be used to determine whether a value is supported. If a value is not supported,
16+
the `decode` and `encode` methods will throw a `UnsupportedValueException` exception. The `decodeIfSupported` and
17+
`encodeIfSupported` methods are useful to encode or decode a value only if it is supported. For unsupported values, the
18+
original value is returned.
1819

19-
interface Decoder
20-
{
21-
public function canDecode(mixed $value): bool;
22-
23-
public function decode(mixed $value): mixed;
24-
25-
public function decodeIfSupported(mixed $value): mixed;
26-
}
27-
28-
interface Encoder
29-
{
30-
public function canEncode(mixed $value): bool;
31-
32-
public function encode(mixed $value): mixed;
33-
34-
public function encodeIfSupported(mixed $value): mixed;
35-
}
36-
```
37-
38-
## Codec Interface
20+
## Codec Interfaces
3921

4022
The `Codec` interface combines decoding and encoding into a single interface. This will be used for most values except
41-
for documents where a more specific `DocumentCodec` is provided.
42-
43-
The base interface supports encoding from a `NativeType` to a `BSONType` and back. Helper methods to determine whether a
44-
value is supported are provided. The `decodeIfSupported` and `encodeIfSupported` methods are useful to have a codec
45-
encode or decode a value only if it is supported. If it is not supported, the original value is returned.
46-
47-
```php
48-
namespace MongoDB\Codec;
49-
50-
interface Codec extends Decoder, Encoder
51-
{
52-
}
53-
```
23+
for documents where a more specific `DocumentCodec` is provided. The `DocumentCodec` interface overrides the `decode`
24+
and `encode` methods from the base `Codec` interface to narrow the return types. Document codecs guarantee to always
25+
encode to a BSON document instance and decode to a PHP object.
5426

55-
## Document Codec
56-
57-
The document codec is special as it is guaranteed to always encode to a BSON document instance and decode to a PHP
58-
object. Document codecs will be used by `MongoDB\Collection` instances to automatically decode BSON data into PHP
59-
objects when reading data, and to encode PHP objects when inserting or replacing data.
60-
61-
```php
62-
namespace MongoDB\Codec;
63-
64-
use MongoDB\BSON\Document;
65-
66-
/**
67-
* @template ObjectType of object
68-
* @extends Codec<ObjectType, Document>
69-
*/
70-
interface DocumentCodec extends Codec
71-
{
72-
}
73-
```
74-
75-
## Built-in codecs
27+
## Built-in Codecs
7628

7729
By default, two codecs are provided: an `ArrayCodec` and an `ObjectCodec`. These two codecs are used to recursively
7830
encode and decode values in arrays and `stdClass` instances, respectively. When encoding or decoding an object,
7931
`ObjectCodec` only handles public properties of the object and ignores private and protected properties.
8032

33+
## Codec Libraries
34+
35+
The `CodecLibrary` class is able to combine several `Decoder`, `Encoder`, and `Codec` instances into a single codec.
36+
When decoding or encoding a value, the library will use the first instance that supports the value. This allows for
37+
easier composition of codecs. A `Decoder`, `Encoder`, or `Codec` implementation may choose to implement the
38+
`KnowsCodecLibrary` interface. In this case, when the codec is added to a library, the library is injected into the
39+
instance using the `attachCodecLibrary` method. This allows the codec to use the library to decode or encode values.
40+
8141
## Future Work
8242

8343
### Using Codecs
@@ -91,10 +51,9 @@ the various `find` and `findAndModify` operations in collections as well as the
9151
collections, databases, and the client object itself.
9252

9353
When writing data, any operation that takes an entire document will use the codec to automatically encode the document.
94-
This is limited to `insertOne`, `insertMany`, `replaceOne`, and `findOneAndReplace` operations in collections. `update`
95-
operations will not use the codec to encode documents, as they only support update operators and can't work with the
96-
entire document.
97-
54+
This is limited to `insertOne`, `insertMany`, `replaceOne`, and `findOneAndReplace` operations in collections as well
55+
as `insertOne` and `replaceOne` operations in bulk writes. `update` operations will not use the codec to encode
56+
documents, as they only support update operators and can't work with the entire document.
9857

9958
### Codecs and type maps
10059

@@ -108,5 +67,5 @@ this case, the type map is used. The precedence order is as follows:
10867
* collection-level `typeMap` option
10968

11069
Codecs are not inherited from the client or the database object, as they are purely used for operations that return
111-
documents. However, database- or client-level aggregation commands will take an operation-level codec option to
70+
documents. However, database- or client-level aggregation commands will take an operation-level `codec` option to
11271
decode the resulting documents.

0 commit comments

Comments
 (0)