Skip to content

v5 #112

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 22, 2021
Merged

v5 #112

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 35 additions & 39 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [5.0.0] - 2021-04-21
### Added
- Sound null-safety support.

### Changed
- Everything. Again. This is another major **BC-breaking** rework. Please refer to
the API documentation, examples and tests.
the API documentation, examples and tests.

## [3.2.3] - 2020-08-06
### Fixed
- Call toJson() on resourceObject when serializing ([\#84](https://github.com/f3ath/json-api-dart/pull/84))

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

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

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

## [3.2.3] - 2020-08-06
### Fixed
- Call toJson() on resourceObject when serializing ([#84](https://github.com/f3ath/json-api-dart/pull/84))


## [3.2.2] - 2020-01-07
### Fixed
- Can not decode related resource which is null ([#77](https://github.com/f3ath/json-api-dart/issues/77))
- Can not decode related resource which is null ([\#77](https://github.com/f3ath/json-api-dart/issues/77))

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

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

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

### Changed
Most of the changes are **BC-BREAKING**.
- `URLBuilder` was renamed to `UrlFactory`.
- `DocumentBuilder` was split into `ServerDocumentFactory` and `ClientDocumentFactory`. Some methods were renamed.
- Static `decodeJson` methods were renamed to `fromJson`.
Expand All @@ -97,7 +95,7 @@ Most of the changes are **BC-BREAKING**.
- The signature of `Controller`.
- `Server` was renamed to `JsonApiServer`.
- `Pagination` was renamed to `PaginationStrategy`.

### Removed
- (Server) `ResourceTarget`, `CollectionTarget`, `RelationshipTarget` classes.
- `QueryParameters` interface.
Expand All @@ -106,81 +104,79 @@ Most of the changes are **BC-BREAKING**.

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

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

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

## [2.0.1] - 2019-07-12
### Fixed
- Readme example was outdated.

## [2.0.0] - 2019-07-12

### Changed
- This package now consolidates the Client, the Server and the Document in one single library.
It does not depend on `json_api_document` and `json_api_server` anymore, please remove these packages
from your `pubspec.yaml`.
It does not depend on `json_api_document` and `json_api_server` anymore, please remove these packages
from your `pubspec.yaml`.
- The min Dart SDK version bumped to `2.3.0`
- The Client requires an instance of HttpClient to be passed to the constructor explicitly.
- Both the Document and the Server have been refactored with lots of **BREAKING CHANGES**.
See the examples and the functional tests for details.
See the examples and the functional tests for details.
- Meta properties are not defensively copied, but set directly. Meta property behavior is unified across
the Document model.
the Document model.

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


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

## [1.0.0] - 2019-03-20
### Changed
- JSON:API Server moved out

## [0.6.0] - 2019-03-25
### Changed
- JSON:API Document moved out
- Renamed `client.removeToOne(...)` to `client.deleteToOne(...)`

## [0.5.0] - 2019-03-21
### Added
- Related collection pagination
- Async operations support

### Changed
- More BC-breaking changes in the Server

### Fixed
- Location headers were incorrectly generated by Server

### Added
- Related collection pagination
- Async operations support
## [1.0.0] - 2019-03-20
### Changed
- JSON:API Server moved out

## [0.4.0] - 2019-03-17
### Added
- Compound documents support in Client (Server-side support is still very limited)

### Changed
- Parsing logic moved out
- Some other BC-breaking changes in the Document
- Huge changes in the Server

### Added
- Compound documents support in Client (Server-side support is still very limited)

### Fixed
- Server was not setting links for resources and relationships

## [0.3.0] - 2019-03-16
### Changed
- Huge BC-breaking refactoring in the Document model which propagated everywhere

### Added
- Resource attributes update
- Resource relationships update

### Changed
- Huge BC-breaking refactoring in the Document model which propagated everywhere

## [0.2.0] - 2019-03-01
### Added
- Improved ResourceController error handling
Expand All @@ -191,15 +187,15 @@ Most of the changes are **BC-BREAKING**.
### Added
- Client: fetch resources, collections, related resources and relationships

[Unreleased]: https://github.com/f3ath/json-api-dart/compare/4.3.0..HEAD
[5.0.0]: https://github.com/f3ath/json-api-dart/compare/3.2.3...5.0.0
[3.2.3]: https://github.com/f3ath/json-api-dart/compare/3.2.2...3.2.3
[4.3.0]: https://github.com/f3ath/json-api-dart/compare/4.2.2...4.3.0
[4.2.2]: https://github.com/f3ath/json-api-dart/compare/4.2.1...4.2.2
[4.2.1]: https://github.com/f3ath/json-api-dart/compare/4.2.0...4.2.1
[4.2.0]: https://github.com/f3ath/json-api-dart/compare/4.1.0...4.2.0
[4.1.0]: https://github.com/f3ath/json-api-dart/compare/4.0.0...4.1.0
[4.0.0]: https://github.com/f3ath/json-api-dart/compare/3.2.2...4.0.0
[3.2.3]: https://github.com/f3ath/json-api-dart/compare/3.2.2..3.2.3
[3.2.2]: https://github.com/f3ath/json-api-dart/compare/3.2.1..3.2.2
[3.2.2]: https://github.com/f3ath/json-api-dart/compare/3.2.1...3.2.2
[3.2.1]: https://github.com/f3ath/json-api-dart/compare/3.2.0...3.2.1
[3.2.0]: https://github.com/f3ath/json-api-dart/compare/3.1.0...3.2.0
[3.1.0]: https://github.com/f3ath/json-api-dart/compare/3.0.0...3.1.0
Expand All @@ -210,10 +206,10 @@ Most of the changes are **BC-BREAKING**.
[2.0.1]: https://github.com/f3ath/json-api-dart/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/f3ath/json-api-dart/compare/1.0.1...2.0.0
[1.0.1]: https://github.com/f3ath/json-api-dart/compare/1.0.0...1.0.1
[1.0.0]: https://github.com/f3ath/json-api-dart/compare/0.6.0...1.0.0
[0.6.0]: https://github.com/f3ath/json-api-dart/compare/0.5.0...0.6.0
[0.5.0]: https://github.com/f3ath/json-api-dart/compare/0.4.0...0.5.0
[1.0.0]: https://github.com/f3ath/json-api-dart/compare/0.6.0...1.0.0
[0.4.0]: https://github.com/f3ath/json-api-dart/compare/0.3.0...0.4.0
[0.3.0]: https://github.com/f3ath/json-api-dart/compare/0.2.0...0.3.0
[0.2.0]: https://github.com/f3ath/json-api-dart/compare/0.1.0...0.2.0
[0.1.0]: https://github.com/f3ath/json-api-dart/releases/tag/0.1.0
[0.1.0]: https://github.com/f3ath/json-api-dart/releases/tag/0.1.0
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
# JSON:API Client and Server for Dart/Flutter. Version 5.
# JSON:API Client and Server

TL;DR:
```dart
import 'package:json_api/client.dart';
import 'package:json_api/routing.dart';

void main() async {
/// Define the server's base URL
final baseUri = 'http://localhost:8080';

/// Use the standard recommended URL structure or implement your own
final uriDesign = StandardUriDesign(Uri.parse(baseUri));

/// The [RoutingClient] is most likely the right choice.
/// It has methods covering many standard use cases.
final client = RoutingClient(uriDesign);

try {
/// Fetch the collection.
/// See other methods to query and manipulate resources.
final response = await client.fetchCollection('colors');

final resources = response.collection;
resources.map((resource) => resource.attributes).forEach((attr) {
final name = attr['name'];
final red = attr['red'];
final green = attr['green'];
final blue = attr['blue'];
print('$name - $red:$green:$blue');
});
} on RequestFailure catch (e) {
/// Catch error response
e.errors.forEach((error) => print('${error.title}'));
}
}
```
This is a work-in-progress. You can help it by submitting a PR with a feature or documentation improvements.



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


[JSON:API]: https://jsonapi.org
36 changes: 27 additions & 9 deletions example/client.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
import 'package:json_api/client.dart';
import 'package:json_api/routing.dart';

// START THE SERVER FIRST!
void main() async {
final host = 'localhost';
final port = 8080;
final uri = Uri(scheme: 'http', host: host, port: port);
final client = RoutingClient(StandardUriDesign(uri));
final response = await client.fetchCollection('colors');
response.collection.map((resource) => resource.attributes).forEach((attr) {
print('${attr['name']} - ${attr['red']}:${attr['green']}:${attr['blue']}');
});
/// Define the server's base URL
final baseUri = 'http://localhost:8080';

/// Use the standard recommended URL structure or implement your own
final uriDesign = StandardUriDesign(Uri.parse(baseUri));

/// The [RoutingClient] is most likely the right choice.
/// It has methods covering many standard use cases.
final client = RoutingClient(uriDesign);

try {
/// Fetch the collection.
/// See other methods to query and manipulate resources.
final response = await client.fetchCollection('colors');

final resources = response.collection;
resources.map((resource) => resource.attributes).forEach((attr) {
final name = attr['name'];
final red = attr['red'];
final green = attr['green'];
final blue = attr['blue'];
print('$name - $red:$green:$blue');
});
} on RequestFailure catch (e) {
/// Catch error response
e.errors.forEach((error) => print('${error.title}'));
}
}
24 changes: 23 additions & 1 deletion lib/client.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
/// JSON:API client for Flutter, browsers and vm.
/// Provides JSON:API client for Flutter, browsers and vm.
///
/// There are two clients implementation provided by this library.
///
/// The firs one, [Client], is the most flexible but low level. It operates
/// generic [Request] and [Response] objects and performs basic operations
/// such as JSON conversion and error handling. It is agnostic to the document
/// structure and accepts any target URIs.
///
/// By default, the [DisposableHandler] is used which internally creates
/// a new instance of Dart built-in HTTP client for each request and then
/// disposes it. If you want more control of the underlying http client,
/// one option can be to use the [PersistentHandler]. To use another HTTP client,
/// such as [dio](https://pub.dev/packages/dio) implement your own wrapper.
///
/// The [codec] performs JSON encoding/decoding. The default implementation
/// uses native `dart:convert`. Provide your own [PayloadCodec] if you need
/// fine-grained control over JSON conversion.
///
/// The [RoutingClient] is a wrapper over [Client] containing methods
/// representing the most common use cases of resource fetching and manipulation.
/// It can conveniently construct and parse JSON:API documents and URIs.
/// The [RoutingClient] should be your default choice.
library client;

export 'package:json_api/src/client/client.dart';
Expand Down
26 changes: 9 additions & 17 deletions lib/src/client/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import 'package:json_api/http.dart';
import 'package:json_api/src/client/disposable_handler.dart';
import 'package:json_api/src/client/request.dart';
import 'package:json_api/src/client/response.dart';
import 'package:json_api/src/client/response/request_failure.dart';

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

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

final json = await _decode(response);
if (StatusCode(response.statusCode).isFailed) {
throw RequestFailure(response, json);
}
return Response(response, json);
final document = await _decode(response);
return Response(response, document);
}

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

Future<Map?> _decode(HttpResponse response) async =>
_isJsonApi(response) ? await _codec.decode(response.body) : null;

/// True if body is not empty and Content-Type is application/vnd.api+json
bool _isJsonApi(HttpResponse response) =>
response.body.isNotEmpty &&
(response.headers['Content-Type'] ?? '')
.toLowerCase()
.startsWith(mediaType);
response.hasDocument ? await _codec.decode(response.body) : null;
}
Loading