11import 'dart:async' ;
22
33import 'package:json_api/document.dart' ;
4- import 'package:json_api/server.dart' ;
4+ import 'package:json_api/src/server/contracts/controller.dart' ;
5+ import 'package:json_api/src/server/numbered_page.dart' ;
56import 'package:uuid/uuid.dart' ;
67
78import 'dao.dart' ;
@@ -12,164 +13,167 @@ class CarsController implements JsonApiController {
1213 CarsController (this .dao);
1314
1415 @override
15- Future fetchCollection (FetchCollection r) async {
16- if (! dao.containsKey (r.route. type)) {
17- return r.notFound ([JsonApiError (detail: 'Unknown resource type' )]);
18- }
19- final page = NumberedPage .fromQueryParameters (r.queryParameters,
20- total: dao[r.route. type].length);
21- return r.collection (
22- dao[r.route. type]
16+ Future fetchCollection (FetchCollectionRequest r) async {
17+ if (! dao.containsKey (r.type)) {
18+ return r.errorNotFound ([JsonApiError (detail: 'Unknown resource type' )]);
19+ }
20+ final page = NumberedPage .fromQueryParameters (r.uri. queryParameters,
21+ total: dao[r.type].length);
22+ return r.sendCollection (
23+ dao[r.type]
2324 .fetchCollection (offset: page.offset)
24- .map (dao[r.route. type].toResource),
25+ .map (dao[r.type].toResource),
2526 page: page);
2627 }
2728
2829 @override
29- Future fetchRelated (FetchRelated r) {
30- if (! dao.containsKey (r.route. type)) {
31- return r.notFound ([JsonApiError (detail: 'Unknown resource type' )]);
30+ Future fetchRelated (FetchRelatedRequest r) {
31+ if (! dao.containsKey (r.type)) {
32+ return r.errorNotFound ([JsonApiError (detail: 'Unknown resource type' )]);
3233 }
33- final res = dao[r.route. type].fetchByIdAsResource (r.route .id);
34+ final res = dao[r.type].fetchByIdAsResource (r.id);
3435 if (res == null ) {
35- return r.notFound ([JsonApiError (detail: 'Resource not found' )]);
36+ return r.errorNotFound ([JsonApiError (detail: 'Resource not found' )]);
3637 }
3738
38- if (res.toOne.containsKey (r.route. relationship)) {
39- final id = res.toOne[r.route. relationship];
39+ if (res.toOne.containsKey (r.relationship)) {
40+ final id = res.toOne[r.relationship];
4041 final resource = dao[id.type].fetchByIdAsResource (id.id);
41- return r.resource (resource);
42+ return r.sendResource (resource);
4243 }
4344
44- if (res.toMany.containsKey (r.route. relationship)) {
45- final resources = res.toMany[r.route. relationship]
45+ if (res.toMany.containsKey (r.relationship)) {
46+ final resources = res.toMany[r.relationship]
4647 .map ((id) => dao[id.type].fetchByIdAsResource (id.id));
47- return r.collection (resources);
48+ return r.sendCollection (resources);
4849 }
49- return r.notFound ([JsonApiError (detail: 'Relationship not found' )]);
50+ return r.errorNotFound ([JsonApiError (detail: 'Relationship not found' )]);
5051 }
5152
5253 @override
53- Future fetchResource (FetchResource r) {
54- if (! dao.containsKey (r.route. type)) {
55- return r.notFound ([JsonApiError (detail: 'Unknown resource type' )]);
54+ Future fetchResource (FetchResourceRequest r) {
55+ if (! dao.containsKey (r.type)) {
56+ return r.errorNotFound ([JsonApiError (detail: 'Unknown resource type' )]);
5657 }
57- final res = dao[r.route. type].fetchByIdAsResource (r.route .id);
58+ final res = dao[r.type].fetchByIdAsResource (r.id);
5859 if (res == null ) {
59- return r.notFound ([JsonApiError (detail: 'Resource not found' )]);
60+ return r.errorNotFound ([JsonApiError (detail: 'Resource not found' )]);
6061 }
61- return r.resource (res);
62+ final fetchById = (Identifier _) => dao[_.type].fetchByIdAsResource (_.id);
63+
64+ final children = res.toOne.values
65+ .map (fetchById)
66+ .followedBy (res.toMany.values.expand ((_) => _.map (fetchById)));
67+
68+ return r.sendResource (res, included: children);
6269 }
6370
6471 @override
65- Future fetchRelationship (FetchRelationship r) {
66- if (! dao.containsKey (r.route. type)) {
67- return r.notFound ([JsonApiError (detail: 'Unknown resource type' )]);
72+ Future fetchRelationship (FetchRelationshipRequest r) {
73+ if (! dao.containsKey (r.type)) {
74+ return r.errorNotFound ([JsonApiError (detail: 'Unknown resource type' )]);
6875 }
69- final res = dao[r.route. type].fetchByIdAsResource (r.route .id);
76+ final res = dao[r.type].fetchByIdAsResource (r.id);
7077 if (res == null ) {
71- return r.notFound ([JsonApiError (detail: 'Resource not found' )]);
78+ return r.errorNotFound ([JsonApiError (detail: 'Resource not found' )]);
7279 }
7380
74- if (res.toOne.containsKey (r.route. relationship)) {
75- final id = res.toOne[r.route. relationship];
76- return r.toOne (id);
81+ if (res.toOne.containsKey (r.relationship)) {
82+ final id = res.toOne[r.relationship];
83+ return r.sendToOne (id);
7784 }
7885
79- if (res.toMany.containsKey (r.route. relationship)) {
80- final ids = res.toMany[r.route. relationship];
81- return r.toMany (ids);
86+ if (res.toMany.containsKey (r.relationship)) {
87+ final ids = res.toMany[r.relationship];
88+ return r.sendToMany (ids);
8289 }
83- return r.notFound ([JsonApiError (detail: 'Relationship not found' )]);
90+ return r.errorNotFound ([JsonApiError (detail: 'Relationship not found' )]);
8491 }
8592
8693 @override
87- Future deleteResource (DeleteResource r) {
88- if (! dao.containsKey (r.route. type)) {
89- return r.notFound ([JsonApiError (detail: 'Unknown resource type' )]);
94+ Future deleteResource (DeleteResourceRequest r) {
95+ if (! dao.containsKey (r.type)) {
96+ return r.errorNotFound ([JsonApiError (detail: 'Unknown resource type' )]);
9097 }
91- final res = dao[r.route. type].fetchByIdAsResource (r.route .id);
98+ final res = dao[r.type].fetchByIdAsResource (r.id);
9299 if (res == null ) {
93- return r.notFound ([JsonApiError (detail: 'Resource not found' )]);
100+ return r.errorNotFound ([JsonApiError (detail: 'Resource not found' )]);
94101 }
95- final dependenciesCount = dao[r.route. type].deleteById (r.route .id);
102+ final dependenciesCount = dao[r.type].deleteById (r.id);
96103 if (dependenciesCount == 0 ) {
97- return r.noContent ();
104+ return r.sendNoContent ();
98105 }
99- return r.meta ({'dependenciesCount' : dependenciesCount});
106+ return r.sendMeta ({'dependenciesCount' : dependenciesCount});
100107 }
101108
102- Future createResource (CreateResource r) async {
103- if (! dao.containsKey (r.route. type)) {
104- return r.notFound ([JsonApiError (detail: 'Unknown resource type' )]);
109+ Future createResource (CreateResourceRequest r) async {
110+ if (! dao.containsKey (r.type)) {
111+ return r.errorNotFound ([JsonApiError (detail: 'Unknown resource type' )]);
105112 }
106- final resource = await r.resource ();
107- if (r.route.type != resource.type) {
108- return r.conflict ([JsonApiError (detail: 'Incompatible type' )]);
113+ if (r.type != r.resource.type) {
114+ return r.errorConflict ([JsonApiError (detail: 'Incompatible type' )]);
109115 }
110116
111- if (resource.hasId) {
112- if (dao[r.route.type].fetchById (resource.id) != null ) {
113- return r.conflict ([JsonApiError (detail: 'Resource already exists' )]);
117+ if (r.resource.hasId) {
118+ if (dao[r.type].fetchById (r.resource.id) != null ) {
119+ return r
120+ .errorConflict ([JsonApiError (detail: 'Resource already exists' )]);
114121 }
115- final created = dao[r.route.type].create (resource);
116- dao[r.route.type].insert (created);
117- return r.noContent ();
118- }
119-
120- final created = dao[r.route.type].create (Resource (
121- resource.type, Uuid ().v4 (),
122- attributes: resource.attributes,
123- toMany: resource.toMany,
124- toOne: resource.toOne));
125- dao[r.route.type].insert (created);
126- return r.created (dao[r.route.type].toResource (created));
122+ final created = dao[r.type].create (r.resource);
123+ dao[r.type].insert (created);
124+ return r.sendNoContent ();
125+ }
126+
127+ final created = dao[r.type].create (Resource (r.resource.type, Uuid ().v4 (),
128+ attributes: r.resource.attributes,
129+ toMany: r.resource.toMany,
130+ toOne: r.resource.toOne));
131+ dao[r.type].insert (created);
132+ return r.sendCreated (dao[r.type].toResource (created));
127133 }
128134
129135 @override
130- Future updateResource (UpdateResource r) async {
131- if (! dao.containsKey (r.route. type)) {
132- return r.notFound ([JsonApiError (detail: 'Unknown resource type' )]);
136+ Future updateResource (UpdateResourceRequest r) async {
137+ if (! dao.containsKey (r.type)) {
138+ return r.errorNotFound ([JsonApiError (detail: 'Unknown resource type' )]);
133139 }
134- final resource = await r.resource ();
135- if (r.route.type != resource.type) {
136- return r.conflict ([JsonApiError (detail: 'Incompatible type' )]);
140+ if (r.type != r.resource.type) {
141+ return r.errorConflict ([JsonApiError (detail: 'Incompatible type' )]);
137142 }
138- if (dao[r.route. type].fetchById (r.route .id) == null ) {
139- return r.notFound ([JsonApiError (detail: 'Resource not found' )]);
143+ if (dao[r.type].fetchById (r.id) == null ) {
144+ return r.errorNotFound ([JsonApiError (detail: 'Resource not found' )]);
140145 }
141- final updated = dao[r.route. type].update (r.route. id, resource);
146+ final updated = dao[r.type].update (r.id, r. resource);
142147 if (updated == null ) {
143- return r.noContent ();
148+ return r.sendNoContent ();
144149 }
145- return r.updated (updated);
150+ return r.sendUpdated (updated);
146151 }
147152
148153 @override
149- Future replaceRelationship ( ReplaceRelationship r) async {
150- if (! dao.containsKey (r.route. type)) {
151- return r.notFound ([JsonApiError (detail: 'Unknown resource type' )]);
154+ Future replaceToOne ( ReplaceToOneRequest r) async {
155+ if (! dao.containsKey (r.type)) {
156+ return r.errorNotFound ([JsonApiError (detail: 'Unknown resource type' )]);
152157 }
153- final rel = await r.relationshipData ();
154- if (rel is ToOne ) {
155- dao[r.route.type]
156- .replaceToOne (r.route.id, r.route.relationship, rel.toIdentifier ());
157- return r.noContent ();
158- }
159- if (rel is ToMany ) {
160- dao[r.route.type]
161- .replaceToMany (r.route.id, r.route.relationship, rel.identifiers);
162- return r.noContent ();
158+ dao[r.type].replaceToOne (r.id, r.relationship, r.identifier);
159+ return r.sendNoContent ();
160+ }
161+
162+ @override
163+ Future replaceToMany (ReplaceToManyRequest r) async {
164+ if (! dao.containsKey (r.type)) {
165+ return r.errorNotFound ([JsonApiError (detail: 'Unknown resource type' )]);
163166 }
167+ dao[r.type].replaceToMany (r.id, r.relationship, r.identifiers);
168+ return r.sendNoContent ();
164169 }
165170
166171 @override
167- Future addToRelationship ( AddToRelationship r) async {
168- if (! dao.containsKey (r.route. type)) {
169- return r.notFound ([JsonApiError (detail: 'Unknown resource type' )]);
172+ Future addToMany ( AddToManyRequest r) async {
173+ if (! dao.containsKey (r.type)) {
174+ return r.errorNotFound ([JsonApiError (detail: 'Unknown resource type' )]);
170175 }
171- final result = dao[r.route.type]
172- .addToMany (r.route.id, r.route.relationship, await r.identifiers ());
173- return r.toMany (result);
176+ final result = dao[r.type].addToMany (r.id, r.relationship, r.identifiers);
177+ return r.sendToMany (result);
174178 }
175179}
0 commit comments