Skip to content

Commit 2bdec4c

Browse files
authored
v5 (#112)
1 parent 4c2dbe9 commit 2bdec4c

14 files changed

+250
-146
lines changed

CHANGELOG.md

+35-39
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [Unreleased]
7+
## [5.0.0] - 2021-04-21
88
### Added
99
- Sound null-safety support.
1010

1111
### Changed
1212
- Everything. Again. This is another major **BC-breaking** rework. Please refer to
13-
the API documentation, examples and tests.
13+
the API documentation, examples and tests.
14+
15+
## [3.2.3] - 2020-08-06
16+
### Fixed
17+
- Call toJson() on resourceObject when serializing ([\#84](https://github.com/f3ath/json-api-dart/pull/84))
1418

1519
## [4.3.0] - 2020-07-30
1620
### Added
@@ -34,7 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3438

3539
### Changed
3640
- The client will not attempt to decode the body of the HTTP response with error status if the correct Content-Type
37-
is missing. Before in such cases a `FormatException` would be thrown ([pr](https://github.com/f3ath/json-api-dart/pull/98))
41+
is missing. Before in such cases a `FormatException` would be thrown ([pr](https://github.com/f3ath/json-api-dart/pull/98))
3842

3943
## [4.1.0] - 2020-05-28
4044
### Changed
@@ -44,18 +48,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4448
### Changed
4549
- Everything. This is a major **BC-breaking** rework which affected pretty much all areas. Please refer to the documentation.
4650

47-
## [3.2.3] - 2020-08-06
48-
### Fixed
49-
- Call toJson() on resourceObject when serializing ([#84](https://github.com/f3ath/json-api-dart/pull/84))
50-
51-
5251
## [3.2.2] - 2020-01-07
5352
### Fixed
54-
- Can not decode related resource which is null ([#77](https://github.com/f3ath/json-api-dart/issues/77))
53+
- Can not decode related resource which is null ([\#77](https://github.com/f3ath/json-api-dart/issues/77))
5554

5655
## [3.2.1] - 2020-01-01
5756
### Fixed
58-
- Incorrect URL in the example in the Client documentation ([#74](https://github.com/f3ath/json-api-dart/issues/74))
57+
- Incorrect URL in the example in the Client documentation ([\#74](https://github.com/f3ath/json-api-dart/issues/74))
5958

6059
## [3.2.0] - 2019-12-30
6160
### Added
@@ -81,13 +80,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8180

8281
## [3.0.0] - 2019-12-17
8382
### Added
84-
- Support for custom non-standard links ([#61](https://github.com/f3ath/json-api-dart/issues/61))
83+
- Support for custom non-standard links ([\#61](https://github.com/f3ath/json-api-dart/issues/61))
8584
- Client supports `jsonapi` key in outgoing requests.
8685
- `Document.contentType` constant.
8786
- `IdentifierObject.fromIdentifier` factory method
8887

8988
### Changed
90-
Most of the changes are **BC-BREAKING**.
9189
- `URLBuilder` was renamed to `UrlFactory`.
9290
- `DocumentBuilder` was split into `ServerDocumentFactory` and `ClientDocumentFactory`. Some methods were renamed.
9391
- Static `decodeJson` methods were renamed to `fromJson`.
@@ -97,7 +95,7 @@ Most of the changes are **BC-BREAKING**.
9795
- The signature of `Controller`.
9896
- `Server` was renamed to `JsonApiServer`.
9997
- `Pagination` was renamed to `PaginationStrategy`.
100-
98+
10199
### Removed
102100
- (Server) `ResourceTarget`, `CollectionTarget`, `RelationshipTarget` classes.
103101
- `QueryParameters` interface.
@@ -106,81 +104,79 @@ Most of the changes are **BC-BREAKING**.
106104

107105
## [2.1.0] - 2019-12-04
108106
### Added
109-
- `onHttpCall` hook to enable raw http request/response logging ([#60](https://github.com/f3ath/json-api-dart/issues/60)).
107+
- `onHttpCall` hook to enable raw http request/response logging ([\#60](https://github.com/f3ath/json-api-dart/issues/60)).
110108

111109
## [2.0.3] - 2019-09-29
112110
### Fixed
113111
- Documentation links got broken due to pub.dev update.
114112

115113
## [2.0.2] - 2019-08-01
116114
### Fixed
117-
- Meta members have incorrect type ([#54](https://github.com/f3ath/json-api-dart/issues/54)).
115+
- Meta members have incorrect type ([\#54](https://github.com/f3ath/json-api-dart/issues/54)).
118116

119117
## [2.0.1] - 2019-07-12
120118
### Fixed
121119
- Readme example was outdated.
122120

123121
## [2.0.0] - 2019-07-12
124-
125122
### Changed
126123
- This package now consolidates the Client, the Server and the Document in one single library.
127-
It does not depend on `json_api_document` and `json_api_server` anymore, please remove these packages
128-
from your `pubspec.yaml`.
124+
It does not depend on `json_api_document` and `json_api_server` anymore, please remove these packages
125+
from your `pubspec.yaml`.
129126
- The min Dart SDK version bumped to `2.3.0`
130127
- The Client requires an instance of HttpClient to be passed to the constructor explicitly.
131128
- Both the Document and the Server have been refactored with lots of **BREAKING CHANGES**.
132-
See the examples and the functional tests for details.
129+
See the examples and the functional tests for details.
133130
- Meta properties are not defensively copied, but set directly. Meta property behavior is unified across
134-
the Document model.
131+
the Document model.
135132

136133
### Removed
137134
- `JsonApiParser` is removed. Use the static `decodeJson` methods in the corresponding classes instead.
138135

139-
140136
## [1.0.1] - 2019-04-05
141137
### Fixed
142138
- Bumped the dependencies versions due to a bug in `json_api_document`.
143139

144-
## [1.0.0] - 2019-03-20
145-
### Changed
146-
- JSON:API Server moved out
147-
148140
## [0.6.0] - 2019-03-25
149141
### Changed
150142
- JSON:API Document moved out
151143
- Renamed `client.removeToOne(...)` to `client.deleteToOne(...)`
152144

153145
## [0.5.0] - 2019-03-21
146+
### Added
147+
- Related collection pagination
148+
- Async operations support
149+
154150
### Changed
155151
- More BC-breaking changes in the Server
156152

157153
### Fixed
158154
- Location headers were incorrectly generated by Server
159155

160-
### Added
161-
- Related collection pagination
162-
- Async operations support
156+
## [1.0.0] - 2019-03-20
157+
### Changed
158+
- JSON:API Server moved out
163159

164160
## [0.4.0] - 2019-03-17
161+
### Added
162+
- Compound documents support in Client (Server-side support is still very limited)
163+
165164
### Changed
166165
- Parsing logic moved out
167166
- Some other BC-breaking changes in the Document
168167
- Huge changes in the Server
169168

170-
### Added
171-
- Compound documents support in Client (Server-side support is still very limited)
172-
173169
### Fixed
174170
- Server was not setting links for resources and relationships
175171

176172
## [0.3.0] - 2019-03-16
177-
### Changed
178-
- Huge BC-breaking refactoring in the Document model which propagated everywhere
179-
180173
### Added
181174
- Resource attributes update
182175
- Resource relationships update
183176

177+
### Changed
178+
- Huge BC-breaking refactoring in the Document model which propagated everywhere
179+
184180
## [0.2.0] - 2019-03-01
185181
### Added
186182
- Improved ResourceController error handling
@@ -191,15 +187,15 @@ Most of the changes are **BC-BREAKING**.
191187
### Added
192188
- Client: fetch resources, collections, related resources and relationships
193189

194-
[Unreleased]: https://github.com/f3ath/json-api-dart/compare/4.3.0..HEAD
190+
[5.0.0]: https://github.com/f3ath/json-api-dart/compare/3.2.3...5.0.0
191+
[3.2.3]: https://github.com/f3ath/json-api-dart/compare/3.2.2...3.2.3
195192
[4.3.0]: https://github.com/f3ath/json-api-dart/compare/4.2.2...4.3.0
196193
[4.2.2]: https://github.com/f3ath/json-api-dart/compare/4.2.1...4.2.2
197194
[4.2.1]: https://github.com/f3ath/json-api-dart/compare/4.2.0...4.2.1
198195
[4.2.0]: https://github.com/f3ath/json-api-dart/compare/4.1.0...4.2.0
199196
[4.1.0]: https://github.com/f3ath/json-api-dart/compare/4.0.0...4.1.0
200197
[4.0.0]: https://github.com/f3ath/json-api-dart/compare/3.2.2...4.0.0
201-
[3.2.3]: https://github.com/f3ath/json-api-dart/compare/3.2.2..3.2.3
202-
[3.2.2]: https://github.com/f3ath/json-api-dart/compare/3.2.1..3.2.2
198+
[3.2.2]: https://github.com/f3ath/json-api-dart/compare/3.2.1...3.2.2
203199
[3.2.1]: https://github.com/f3ath/json-api-dart/compare/3.2.0...3.2.1
204200
[3.2.0]: https://github.com/f3ath/json-api-dart/compare/3.1.0...3.2.0
205201
[3.1.0]: https://github.com/f3ath/json-api-dart/compare/3.0.0...3.1.0
@@ -210,10 +206,10 @@ Most of the changes are **BC-BREAKING**.
210206
[2.0.1]: https://github.com/f3ath/json-api-dart/compare/2.0.0...2.0.1
211207
[2.0.0]: https://github.com/f3ath/json-api-dart/compare/1.0.1...2.0.0
212208
[1.0.1]: https://github.com/f3ath/json-api-dart/compare/1.0.0...1.0.1
213-
[1.0.0]: https://github.com/f3ath/json-api-dart/compare/0.6.0...1.0.0
214209
[0.6.0]: https://github.com/f3ath/json-api-dart/compare/0.5.0...0.6.0
215210
[0.5.0]: https://github.com/f3ath/json-api-dart/compare/0.4.0...0.5.0
211+
[1.0.0]: https://github.com/f3ath/json-api-dart/compare/0.6.0...1.0.0
216212
[0.4.0]: https://github.com/f3ath/json-api-dart/compare/0.3.0...0.4.0
217213
[0.3.0]: https://github.com/f3ath/json-api-dart/compare/0.2.0...0.3.0
218214
[0.2.0]: https://github.com/f3ath/json-api-dart/compare/0.1.0...0.2.0
219-
[0.1.0]: https://github.com/f3ath/json-api-dart/releases/tag/0.1.0
215+
[0.1.0]: https://github.com/f3ath/json-api-dart/releases/tag/0.1.0

README.md

+40-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,44 @@
1-
# JSON:API Client and Server for Dart/Flutter. Version 5.
1+
# JSON:API Client and Server
2+
3+
TL;DR:
4+
```dart
5+
import 'package:json_api/client.dart';
6+
import 'package:json_api/routing.dart';
7+
8+
void main() async {
9+
/// Define the server's base URL
10+
final baseUri = 'http://localhost:8080';
11+
12+
/// Use the standard recommended URL structure or implement your own
13+
final uriDesign = StandardUriDesign(Uri.parse(baseUri));
14+
15+
/// The [RoutingClient] is most likely the right choice.
16+
/// It has methods covering many standard use cases.
17+
final client = RoutingClient(uriDesign);
18+
19+
try {
20+
/// Fetch the collection.
21+
/// See other methods to query and manipulate resources.
22+
final response = await client.fetchCollection('colors');
23+
24+
final resources = response.collection;
25+
resources.map((resource) => resource.attributes).forEach((attr) {
26+
final name = attr['name'];
27+
final red = attr['red'];
28+
final green = attr['green'];
29+
final blue = attr['blue'];
30+
print('$name - $red:$green:$blue');
31+
});
32+
} on RequestFailure catch (e) {
33+
/// Catch error response
34+
e.errors.forEach((error) => print('${error.title}'));
35+
}
36+
}
37+
```
38+
This is a work-in-progress. You can help it by submitting a PR with a feature or documentation improvements.
39+
40+
241

3-
[JSON:API] is a specification for building JSON APIs. The documentation is a work-in-progress.
442

543

644
[JSON:API]: https://jsonapi.org

example/client.dart

+27-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
11
import 'package:json_api/client.dart';
22
import 'package:json_api/routing.dart';
33

4-
// START THE SERVER FIRST!
54
void main() async {
6-
final host = 'localhost';
7-
final port = 8080;
8-
final uri = Uri(scheme: 'http', host: host, port: port);
9-
final client = RoutingClient(StandardUriDesign(uri));
10-
final response = await client.fetchCollection('colors');
11-
response.collection.map((resource) => resource.attributes).forEach((attr) {
12-
print('${attr['name']} - ${attr['red']}:${attr['green']}:${attr['blue']}');
13-
});
5+
/// Define the server's base URL
6+
final baseUri = 'http://localhost:8080';
7+
8+
/// Use the standard recommended URL structure or implement your own
9+
final uriDesign = StandardUriDesign(Uri.parse(baseUri));
10+
11+
/// The [RoutingClient] is most likely the right choice.
12+
/// It has methods covering many standard use cases.
13+
final client = RoutingClient(uriDesign);
14+
15+
try {
16+
/// Fetch the collection.
17+
/// See other methods to query and manipulate resources.
18+
final response = await client.fetchCollection('colors');
19+
20+
final resources = response.collection;
21+
resources.map((resource) => resource.attributes).forEach((attr) {
22+
final name = attr['name'];
23+
final red = attr['red'];
24+
final green = attr['green'];
25+
final blue = attr['blue'];
26+
print('$name - $red:$green:$blue');
27+
});
28+
} on RequestFailure catch (e) {
29+
/// Catch error response
30+
e.errors.forEach((error) => print('${error.title}'));
31+
}
1432
}

lib/client.dart

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,26 @@
1-
/// JSON:API client for Flutter, browsers and vm.
1+
/// Provides JSON:API client for Flutter, browsers and vm.
2+
///
3+
/// There are two clients implementation provided by this library.
4+
///
5+
/// The firs one, [Client], is the most flexible but low level. It operates
6+
/// generic [Request] and [Response] objects and performs basic operations
7+
/// such as JSON conversion and error handling. It is agnostic to the document
8+
/// structure and accepts any target URIs.
9+
///
10+
/// By default, the [DisposableHandler] is used which internally creates
11+
/// a new instance of Dart built-in HTTP client for each request and then
12+
/// disposes it. If you want more control of the underlying http client,
13+
/// one option can be to use the [PersistentHandler]. To use another HTTP client,
14+
/// such as [dio](https://pub.dev/packages/dio) implement your own wrapper.
15+
///
16+
/// The [codec] performs JSON encoding/decoding. The default implementation
17+
/// uses native `dart:convert`. Provide your own [PayloadCodec] if you need
18+
/// fine-grained control over JSON conversion.
19+
///
20+
/// The [RoutingClient] is a wrapper over [Client] containing methods
21+
/// representing the most common use cases of resource fetching and manipulation.
22+
/// It can conveniently construct and parse JSON:API documents and URIs.
23+
/// The [RoutingClient] should be your default choice.
224
library client;
325

426
export 'package:json_api/src/client/client.dart';

lib/src/client/client.dart

+9-17
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import 'package:json_api/http.dart';
22
import 'package:json_api/src/client/disposable_handler.dart';
33
import 'package:json_api/src/client/request.dart';
44
import 'package:json_api/src/client/response.dart';
5-
import 'package:json_api/src/client/response/request_failure.dart';
65

7-
/// A basic JSON:API client
6+
/// A basic JSON:API client.
7+
///
8+
/// The JSON:API [Request] is converted to [HttpRequest] and sent downstream
9+
/// using the [handler]. Received [HttpResponse] is then converted back to
10+
/// JSON:API [Response]. JSON conversion is performed by the [codec].
811
class Client {
912
const Client(
1013
{PayloadCodec codec = const PayloadCodec(),
@@ -15,8 +18,7 @@ class Client {
1518
final HttpHandler _http;
1619
final PayloadCodec _codec;
1720

18-
/// Sends the [request] to the server.
19-
/// Throws a [RequestFailure] if the server responds with an error.
21+
/// Sends the [request] to the given [uri].
2022
Future<Response> send(Uri uri, Request request) async {
2123
final body = await _encode(request.document);
2224
final response = await _http.handle(HttpRequest(
@@ -31,23 +33,13 @@ class Client {
3133
...request.headers
3234
}));
3335

34-
final json = await _decode(response);
35-
if (StatusCode(response.statusCode).isFailed) {
36-
throw RequestFailure(response, json);
37-
}
38-
return Response(response, json);
36+
final document = await _decode(response);
37+
return Response(response, document);
3938
}
4039

4140
Future<String> _encode(Object? doc) async =>
4241
doc == null ? '' : await _codec.encode(doc);
4342

4443
Future<Map?> _decode(HttpResponse response) async =>
45-
_isJsonApi(response) ? await _codec.decode(response.body) : null;
46-
47-
/// True if body is not empty and Content-Type is application/vnd.api+json
48-
bool _isJsonApi(HttpResponse response) =>
49-
response.body.isNotEmpty &&
50-
(response.headers['Content-Type'] ?? '')
51-
.toLowerCase()
52-
.startsWith(mediaType);
44+
response.hasDocument ? await _codec.decode(response.body) : null;
5345
}

0 commit comments

Comments
 (0)