Skip to content

Commit f653c14

Browse files
authored
3.2.0 (#72)
1 parent 12d13fb commit f653c14

23 files changed

+193
-122
lines changed

CHANGELOG.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,24 @@ 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+
## [3.2.0] - 2019-12-30
8+
### Added
9+
- `matchBase` option to `PathBasedUrlDesign`.
10+
- `Resource.toIdentifier()`method.
11+
12+
### Changed
13+
- (Server, BC-breaking) `JsonApiController` made generic.
14+
15+
### Removed
16+
- The package does not depend on `collection` anymore.
17+
818
## [3.1.0] - 2019-12-19
919
### Added
1020
- (Server) Routing is exposed via `server` library.
1121

1222
### Changed
13-
- (Server) `Controller` renamed to `JsonApiController`.
14-
- (Server) `Response` renamed to `JsonApiResponse`.
23+
- (Server, BC-breaking) `Controller` renamed to `JsonApiController`.
24+
- (Server, BC-breaking) `Response` renamed to `JsonApiResponse`.
1525

1626
### Fixed
1727
- (Server) Response classes had `included` member initialized to `[]` by default. Now the default is `null`.
@@ -128,7 +138,8 @@ Most of the changes are **BC-BREAKING**.
128138
### Added
129139
- Client: fetch resources, collections, related resources and relationships
130140

131-
[Unreleased]: https://github.com/f3ath/json-api-dart/compare/3.1.0...HEAD
141+
[Unreleased]: https://github.com/f3ath/json-api-dart/compare/3.2.0...HEAD
142+
[3.2.0]: https://github.com/f3ath/json-api-dart/compare/3.1.0...3.2.0
132143
[3.1.0]: https://github.com/f3ath/json-api-dart/compare/3.0.0...3.1.0
133144
[3.0.0]: https://github.com/f3ath/json-api-dart/compare/2.1.0...3.0.0
134145
[2.1.0]: https://github.com/f3ath/json-api-dart/compare/2.0.3...2.1.0

example/cars_server.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ Future<HttpServer> createServer(InternetAddress addr, int port) async {
6060

6161
final httpServer = await HttpServer.bind(addr, port);
6262
final urlDesign = PathBasedUrlDesign(Uri.parse('http://localhost:$port'));
63-
final documentFactory =
64-
ServerDocumentFactory(urlDesign, pagination: pagination);
65-
final jsonApiServer = JsonApiServer(urlDesign, controller, documentFactory);
63+
final jsonApiServer = JsonApiServer(urlDesign, controller,
64+
documentFactory:
65+
ServerDocumentFactory(urlDesign, pagination: pagination));
6666

6767
unawaited(httpServer.forEach(jsonApiServer.serve));
6868
return httpServer;

example/cars_server/controller.dart

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
import 'dart:async';
22

33
import 'package:json_api/document.dart';
4+
import 'package:json_api/query.dart';
45
import 'package:json_api/server.dart';
56
import 'package:uuid/uuid.dart';
67

78
import 'dao.dart';
89
import 'job_queue.dart';
910

10-
class CarsController implements JsonApiController {
11+
class CarsController
12+
implements JsonApiController<JsonApiRequest, JsonApiResponse> {
1113
final Map<String, DAO> _dao;
1214

1315
final PaginationStrategy _pagination;
1416

1517
CarsController(this._dao, this._pagination);
1618

1719
@override
18-
JsonApiResponse fetchCollection(String type, Uri uri) {
19-
final page = Page.fromUri(uri);
20+
JsonApiResponse fetchCollection(String type, JsonApiRequest request) {
21+
final page = Page.fromUri(request.requestedUri);
2022
final dao = _getDaoOrThrow(type);
2123
final collection =
2224
dao.fetchCollection(_pagination.limit(page), _pagination.offset(page));
@@ -26,9 +28,9 @@ class CarsController implements JsonApiController {
2628

2729
@override
2830
JsonApiResponse fetchRelated(
29-
String type, String id, String relationship, Uri uri) {
31+
String type, String id, String relationship, JsonApiRequest request) {
3032
final res = _fetchResourceOrThrow(type, id);
31-
final page = Page.fromUri(uri);
33+
final page = Page.fromUri(request.requestedUri);
3234
if (res.toOne.containsKey(relationship)) {
3335
final id = res.toOne[relationship];
3436
final resource = _dao[id.type].fetchByIdAsResource(id.id);
@@ -47,10 +49,11 @@ class CarsController implements JsonApiController {
4749
}
4850

4951
@override
50-
JsonApiResponse fetchResource(String type, String id, Uri uri) {
52+
JsonApiResponse fetchResource(
53+
String type, String id, JsonApiRequest request) {
5154
final dao = _getDaoOrThrow(type);
5255
final obj = dao.fetchById(id);
53-
final include = Include.fromUri(uri);
56+
final include = Include.fromUri(request.requestedUri);
5457

5558
if (obj == null) {
5659
return ErrorResponse.notFound(
@@ -74,7 +77,7 @@ class CarsController implements JsonApiController {
7477

7578
@override
7679
JsonApiResponse fetchRelationship(
77-
String type, String id, String relationship, Uri uri) {
80+
String type, String id, String relationship, JsonApiRequest request) {
7881
final res = _fetchResourceOrThrow(type, id);
7982

8083
if (res.toOne.containsKey(relationship)) {
@@ -89,7 +92,8 @@ class CarsController implements JsonApiController {
8992
}
9093

9194
@override
92-
JsonApiResponse deleteResource(String type, String id) {
95+
JsonApiResponse deleteResource(
96+
String type, String id, JsonApiRequest request) {
9397
final dao = _getDaoOrThrow(type);
9498

9599
final res = dao.fetchByIdAsResource(id);
@@ -105,7 +109,8 @@ class CarsController implements JsonApiController {
105109
}
106110

107111
@override
108-
JsonApiResponse createResource(String type, Resource resource) {
112+
JsonApiResponse createResource(
113+
String type, Resource resource, JsonApiRequest request) {
109114
final dao = _getDaoOrThrow(type);
110115

111116
_throwIfIncompatibleTypes(type, resource);
@@ -140,7 +145,8 @@ class CarsController implements JsonApiController {
140145
}
141146

142147
@override
143-
JsonApiResponse updateResource(String type, String id, Resource resource) {
148+
JsonApiResponse updateResource(
149+
String type, String id, Resource resource, JsonApiRequest request) {
144150
final dao = _getDaoOrThrow(type);
145151

146152
_throwIfIncompatibleTypes(type, resource);
@@ -156,8 +162,8 @@ class CarsController implements JsonApiController {
156162
}
157163

158164
@override
159-
JsonApiResponse replaceToOne(
160-
String type, String id, String relationship, Identifier identifier) {
165+
JsonApiResponse replaceToOne(String type, String id, String relationship,
166+
Identifier identifier, JsonApiRequest request) {
161167
final dao = _getDaoOrThrow(type);
162168

163169
dao.replaceToOne(id, relationship, identifier);
@@ -166,7 +172,7 @@ class CarsController implements JsonApiController {
166172

167173
@override
168174
JsonApiResponse replaceToMany(String type, String id, String relationship,
169-
List<Identifier> identifiers) {
175+
List<Identifier> identifiers, JsonApiRequest request) {
170176
final dao = _getDaoOrThrow(type);
171177

172178
dao.replaceToMany(id, relationship, identifiers);
@@ -175,7 +181,7 @@ class CarsController implements JsonApiController {
175181

176182
@override
177183
JsonApiResponse addToMany(String type, String id, String relationship,
178-
List<Identifier> identifiers) {
184+
List<Identifier> identifiers, JsonApiRequest request) {
179185
final dao = _getDaoOrThrow(type);
180186

181187
return ToManyResponse(

lib/server.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
/// **The API is not stable!**
88
library server;
99

10-
export 'package:json_api/query.dart';
11-
export 'package:json_api/src/server/http_method.dart';
1210
export 'package:json_api/src/server/json_api_controller.dart';
11+
export 'package:json_api/src/server/json_api_request.dart';
1312
export 'package:json_api/src/server/json_api_server.dart';
1413
export 'package:json_api/src/server/pagination/fixed_size_page.dart';
1514
export 'package:json_api/src/server/pagination/pagination_strategy.dart';
@@ -30,4 +29,3 @@ export 'package:json_api/src/server/response/to_one_response.dart';
3029
export 'package:json_api/src/server/routing/route.dart';
3130
export 'package:json_api/src/server/routing/route_factory.dart';
3231
export 'package:json_api/src/server/server_document_factory.dart';
33-
export 'package:json_api/url_design.dart';

lib/src/client/json_api_client.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class JsonApiClient {
3636
/// You have to create and pass an instance of the [httpClient] yourself.
3737
/// Do not forget to call [httpClient.close()] when you're done using
3838
/// the JSON:API client.
39-
/// The [onHttpCall] hook, if passed, gets called when an http response is
39+
/// The [onHttpCall] hook, if passed, gets called when an http response is
4040
/// received from the HTTP Client.
4141
JsonApiClient(this.httpClient,
4242
{ClientDocumentFactory builder, OnHttpCall onHttpCall})

lib/src/document/relationship.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ class ToOne extends Relationship {
9595
/// Converts to [Identifier].
9696
/// For empty relationships returns null.
9797
Identifier unwrap() => linkage?.unwrap();
98+
99+
/// Same as [unwrap()]
100+
Identifier get identifier => unwrap();
98101
}
99102

100103
/// Relationship to-many
@@ -134,5 +137,8 @@ class ToMany extends Relationship {
134137

135138
/// Converts to List<Identifier>.
136139
/// For empty relationships returns an empty List.
137-
List<Identifier> get identifiers => linkage.map((_) => _.unwrap()).toList();
140+
List<Identifier> unwrap() => linkage.map((_) => _.unwrap()).toList();
141+
142+
/// Same as [unwrap()]
143+
List<Identifier> get identifiers => unwrap();
138144
}

lib/src/document/resource.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ class Resource {
3636
ArgumentError.checkNotNull(type, 'type');
3737
}
3838

39+
Identifier toIdentifier() {
40+
if (id == null) {
41+
throw StateError('Can not create an Identifier with id==null');
42+
}
43+
return Identifier(type, id);
44+
}
45+
3946
@override
4047
String toString() => 'Resource(${type}:${id})';
4148
}

lib/src/document/resource_collection_data.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,13 @@ class ResourceCollectionData extends PrimaryData {
4141
/// The link to the prev page. May be null.
4242
Link get prev => (links ?? {})['prev'];
4343

44+
/// Returns a list of resources contained in the collection
4445
List<Resource> unwrap() => collection.map((_) => _.unwrap()).toList();
4546

47+
/// Returns a map of resources indexed by ids
48+
Map<String, Resource> unwrapToMap() =>
49+
Map.fromIterable(unwrap(), key: (r) => r.id);
50+
4651
@override
4752
Map<String, Object> toJson() => {
4853
...super.toJson(),

lib/src/server/http_method.dart

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,32 @@
1-
import 'dart:async';
2-
31
import 'package:json_api/document.dart';
42
import 'package:json_api/src/document/identifier.dart';
53
import 'package:json_api/src/document/resource.dart';
6-
import 'package:json_api/src/server/response/json_api_response.dart';
4+
import 'package:json_api/src/server/json_api_request.dart';
75

8-
abstract class JsonApiController {
9-
FutureOr<JsonApiResponse> fetchCollection(String type, Uri uri);
6+
abstract class JsonApiController<Request extends JsonApiRequest, Response> {
7+
Response fetchCollection(String type, Request request);
108

11-
FutureOr<JsonApiResponse> fetchResource(String type, String id, Uri uri);
9+
Response fetchResource(String type, String id, Request request);
1210

13-
FutureOr<JsonApiResponse> fetchRelated(
14-
String type, String id, String relationship, Uri uri);
11+
Response fetchRelated(
12+
String type, String id, String relationship, Request request);
1513

16-
FutureOr<JsonApiResponse> fetchRelationship(
17-
String type, String id, String relationship, Uri uri);
14+
Response fetchRelationship(
15+
String type, String id, String relationship, Request request);
1816

19-
FutureOr<JsonApiResponse> deleteResource(String type, String id);
17+
Response deleteResource(String type, String id, Request request);
2018

21-
FutureOr<JsonApiResponse> createResource(String type, Resource resource);
19+
Response createResource(String type, Resource resource, Request request);
2220

23-
FutureOr<JsonApiResponse> updateResource(
24-
String type, String id, Resource resource);
21+
Response updateResource(
22+
String type, String id, Resource resource, Request request);
2523

26-
FutureOr<JsonApiResponse> replaceToOne(
27-
String type, String id, String relationship, Identifier identifier);
24+
Response replaceToOne(String type, String id, String relationship,
25+
Identifier identifier, Request request);
2826

29-
FutureOr<JsonApiResponse> replaceToMany(String type, String id,
30-
String relationship, List<Identifier> identifiers);
27+
Response replaceToMany(String type, String id, String relationship,
28+
List<Identifier> identifiers, Request request);
3129

32-
FutureOr<JsonApiResponse> addToMany(String type, String id,
33-
String relationship, List<Identifier> identifiers);
30+
Response addToMany(String type, String id, String relationship,
31+
List<Identifier> identifiers, Request request);
3432
}

lib/src/server/json_api_request.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// JSON:API HTTP request
2+
class JsonApiRequest {
3+
JsonApiRequest(this.method, this.requestedUri, this.body);
4+
5+
/// Requested URI
6+
final Uri requestedUri;
7+
8+
/// JSON-decoded body, may be null
9+
final Object body;
10+
11+
/// HTTP method
12+
final String method;
13+
}

lib/src/server/json_api_server.dart

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import 'dart:async';
22
import 'dart:convert';
33
import 'dart:io';
44

5-
import 'package:json_api/src/server/http_method.dart';
65
import 'package:json_api/src/server/json_api_controller.dart';
6+
import 'package:json_api/src/server/json_api_request.dart';
77
import 'package:json_api/src/server/response/error_response.dart';
88
import 'package:json_api/src/server/response/json_api_response.dart';
99
import 'package:json_api/src/server/routing/route_factory.dart';
@@ -17,9 +17,10 @@ class JsonApiServer {
1717
final String allowOrigin;
1818
final RouteFactory routeMapper;
1919

20-
JsonApiServer(this.urlDesign, this.controller, this.documentFactory,
21-
{this.allowOrigin = '*'})
22-
: routeMapper = RouteFactory();
20+
JsonApiServer(this.urlDesign, this.controller,
21+
{this.allowOrigin = '*', ServerDocumentFactory documentFactory})
22+
: routeMapper = RouteFactory(),
23+
documentFactory = documentFactory ?? ServerDocumentFactory(urlDesign);
2324

2425
Future serve(HttpRequest request) async {
2526
final response = await _call(controller, request);
@@ -33,12 +34,13 @@ class JsonApiServer {
3334

3435
Future<JsonApiResponse> _call(
3536
JsonApiController controller, HttpRequest request) async {
36-
final method = HttpMethod(request.method);
3737
final body = await _getBody(request);
38+
final jsonApiRequest =
39+
JsonApiRequest(request.method, request.requestedUri, body);
3840
try {
3941
return await urlDesign
4042
.match(request.requestedUri, routeMapper)
41-
.call(controller, request.requestedUri, method, body);
43+
.call(controller, jsonApiRequest);
4244
} on ErrorResponse catch (error) {
4345
return error;
4446
}

0 commit comments

Comments
 (0)