@@ -17,109 +17,185 @@ import 'package:ht_shared/ht_shared.dart'; // Import models
1717Future <Response > onRequest (RequestContext context, String id) async {
1818 // Read dependencies provided by middleware
1919 final modelName = context.read <String >();
20+ // Read ModelConfig for fromJson/getId (needed for PUT)
2021 final modelConfig = context.read <ModelConfig <dynamic >>();
2122
22- // Determine which repository to use based on the model name
23- // Assumes repositories are provided globally (e.g., in routes/_middleware.dart)
24- HtDataRepository <dynamic > repository;
2523 try {
26- switch (modelName) {
27- case 'headline' :
28- repository = context.read <HtDataRepository <Headline >>();
29- case 'category' :
30- repository = context.read <HtDataRepository <Category >>();
31- case 'source' :
32- repository = context.read <HtDataRepository <Source >>();
33- case 'country' : // Added case for Country
34- repository = context.read <HtDataRepository <Country >>();
35- default :
36- // This should technically be caught by the middleware,
37- // but added for safety.
24+ // --- GET Request ---
25+ if (context.request.method == HttpMethod .get ) {
26+ Map <String , dynamic > itemJson;
27+ try {
28+ switch (modelName) {
29+ case 'headline' :
30+ final repo = context.read <HtDataRepository <Headline >>();
31+ final item = await repo.read (id);
32+ // Serialize using the specific model's toJson method
33+ itemJson = item.toJson ();
34+ case 'category' :
35+ final repo = context.read <HtDataRepository <Category >>();
36+ final item = await repo.read (id);
37+ itemJson = item.toJson ();
38+ case 'source' :
39+ final repo = context.read <HtDataRepository <Source >>();
40+ final item = await repo.read (id);
41+ itemJson = item.toJson ();
42+ case 'country' :
43+ final repo = context.read <HtDataRepository <Country >>();
44+ final item = await repo.read (id);
45+ itemJson = item.toJson ();
46+ default :
47+ return Response (
48+ statusCode: HttpStatus .internalServerError,
49+ body:
50+ 'Internal Server Error: Unsupported model type "$modelName " reached handler.' ,
51+ );
52+ }
53+ } catch (e) {
54+ // Catch potential provider errors during context.read
55+ print (
56+ 'Error reading repository provider for model "$modelName " in GET [id]: $e ' ,
57+ );
3858 return Response (
3959 statusCode: HttpStatus .internalServerError,
4060 body:
41- 'Internal Server Error: Unsupported model type "$modelName " reached handler .' ,
61+ 'Internal Server Error: Could not resolve repository for model "$modelName ".' ,
4262 );
63+ }
64+ // Return the serialized item
65+ return Response .json (body: itemJson);
4366 }
44- } catch (e) {
45- // Catch potential provider errors if a repository wasn't provided correctly
46- print ('Error reading repository provider for model "$modelName ": $e ' );
47- return Response (
48- statusCode: HttpStatus .internalServerError,
49- body:
50- 'Internal Server Error: Could not resolve repository for model "$modelName ".' ,
51- );
52- }
53-
54- try {
55- switch (context.request.method) {
56- case HttpMethod .get :
57- final item = await repository.read (id);
58- // Serialize using the model-specific toJson from ModelConfig
59- return Response .json (body: modelConfig.toJson (item));
6067
61- case HttpMethod .put:
62- final requestBody =
63- await context.request.json () as Map <String , dynamic >? ;
64- if (requestBody == null ) {
65- return Response (
66- statusCode: HttpStatus .badRequest,
67- body: 'Missing or invalid request body.' ,
68- );
69- }
70- // Deserialize using the model-specific fromJson from ModelConfig
71- final itemToUpdate = modelConfig.fromJson (requestBody);
68+ // --- PUT Request ---
69+ if (context.request.method == HttpMethod .put) {
70+ final requestBody = await context.request.json () as Map <String , dynamic >? ;
71+ if (requestBody == null ) {
72+ return Response (
73+ statusCode: HttpStatus .badRequest,
74+ body: 'Missing or invalid request body.' ,
75+ );
76+ }
7277
73- // Optional: Validate ID consistency if needed (depends on requirements)
74- final incomingId = modelConfig.getId (itemToUpdate);
75- if (incomingId != id) {
76- return Response (
77- statusCode: HttpStatus .badRequest,
78- body:
79- 'Bad Request: ID in request body ("$incomingId ") does not match ID in path ("$id ").' ,
80- );
81- }
78+ // Deserialize using ModelConfig's fromJson
79+ final itemToUpdate = modelConfig.fromJson (requestBody);
8280
83- final updatedItem = await repository.update (id, itemToUpdate);
84- // Serialize the response using the model-specific toJson
85- return Response .json (body: modelConfig.toJson (updatedItem));
81+ // Validate ID consistency using ModelConfig's getId
82+ final incomingId = modelConfig.getId (itemToUpdate);
83+ if (incomingId != id) {
84+ return Response (
85+ statusCode: HttpStatus .badRequest,
86+ body:
87+ 'Bad Request: ID in request body ("$incomingId ") does not match ID in path ("$id ").' ,
88+ );
89+ }
8690
87- case HttpMethod .delete:
88- await repository.delete (id);
89- // Return 204 No Content for successful deletion
90- return Response (statusCode: HttpStatus .noContent);
91+ Map <String , dynamic > updatedJson;
92+ try {
93+ switch (modelName) {
94+ case 'headline' :
95+ final repo = context.read <HtDataRepository <Headline >>();
96+ // Cast itemToUpdate to the specific type expected by the repository's update method
97+ final updatedItem = await repo.update (id, itemToUpdate as Headline );
98+ // Serialize using the specific model's toJson method
99+ updatedJson = updatedItem.toJson ();
100+ case 'category' :
101+ final repo = context.read <HtDataRepository <Category >>();
102+ final updatedItem = await repo.update (id, itemToUpdate as Category );
103+ updatedJson = updatedItem.toJson ();
104+ case 'source' :
105+ final repo = context.read <HtDataRepository <Source >>();
106+ final updatedItem = await repo.update (id, itemToUpdate as Source );
107+ updatedJson = updatedItem.toJson ();
108+ case 'country' :
109+ final repo = context.read <HtDataRepository <Country >>();
110+ final updatedItem = await repo.update (id, itemToUpdate as Country );
111+ updatedJson = updatedItem.toJson ();
112+ default :
113+ return Response (
114+ statusCode: HttpStatus .internalServerError,
115+ body:
116+ 'Internal Server Error: Unsupported model type "$modelName " reached handler.' ,
117+ );
118+ }
119+ } catch (e) {
120+ // Catch potential provider errors during context.read
121+ print (
122+ 'Error reading repository provider for model "$modelName " in PUT [id]: $e ' ,
123+ );
124+ return Response (
125+ statusCode: HttpStatus .internalServerError,
126+ body:
127+ 'Internal Server Error: Could not resolve repository for model "$modelName ".' ,
128+ );
129+ }
130+ // Return the serialized updated item
131+ return Response .json (body: updatedJson);
132+ }
91133
92- // Methods not allowed on the item endpoint
93- case HttpMethod .post: // POST is for collection endpoint
94- case HttpMethod
95- .patch: // PATCH could be added if partial updates are needed
96- case HttpMethod .head:
97- case HttpMethod .options:
98- return Response (statusCode: HttpStatus .methodNotAllowed);
134+ // --- DELETE Request ---
135+ if (context.request.method == HttpMethod .delete) {
136+ try {
137+ // No serialization needed, just call delete based on type
138+ switch (modelName) {
139+ case 'headline' :
140+ await context.read <HtDataRepository <Headline >>().delete (id);
141+ case 'category' :
142+ await context.read <HtDataRepository <Category >>().delete (id);
143+ case 'source' :
144+ await context.read <HtDataRepository <Source >>().delete (id);
145+ case 'country' :
146+ await context.read <HtDataRepository <Country >>().delete (id);
147+ default :
148+ return Response (
149+ statusCode: HttpStatus .internalServerError,
150+ body:
151+ 'Internal Server Error: Unsupported model type "$modelName " reached handler.' ,
152+ );
153+ }
154+ } catch (e) {
155+ // Catch potential provider errors during context.read
156+ print (
157+ 'Error reading repository provider for model "$modelName " in DELETE [id]: $e ' ,
158+ );
159+ return Response (
160+ statusCode: HttpStatus .internalServerError,
161+ body:
162+ 'Internal Server Error: Could not resolve repository for model "$modelName ".' ,
163+ );
164+ }
165+ // Return 204 No Content for successful deletion
166+ return Response (statusCode: HttpStatus .noContent);
99167 }
168+
169+ // --- Other Methods ---
170+ // Methods not allowed on the item endpoint
171+ return Response (statusCode: HttpStatus .methodNotAllowed);
100172 } on NotFoundException catch (e) {
101173 // Handle specific case where the item ID is not found
174+ // This should be caught by the central error handler, but added as fallback
102175 return Response (statusCode: HttpStatus .notFound, body: e.message);
103176 } on HtHttpException catch (e) {
104177 // Handle other known HTTP exceptions
178+ // These should ideally be caught by the central error handler middleware
105179 if (e is BadRequestException ) {
106180 return Response (statusCode: HttpStatus .badRequest, body: e.message);
107181 }
108- print ('HtHttpException occurred: $e ' );
182+ print ('HtHttpException occurred in /data/[id].dart : $e ' );
109183 return Response (
110184 statusCode: HttpStatus .internalServerError,
111185 body: 'API Error: ${e .message }' ,
112186 );
113187 } on FormatException catch (e) {
114188 // Handle potential JSON parsing/serialization errors during PUT
115- print ('FormatException occurred: $e ' );
189+ print ('FormatException occurred in /data/[id].dart : $e ' );
116190 return Response (
117191 statusCode: HttpStatus .badRequest,
118192 body: 'Invalid data format: ${e .message }' ,
119193 );
120194 } catch (e, stackTrace) {
121195 // Catch any other unexpected errors
122- print ('Unexpected error in /data/[id] handler: $e \n $stackTrace ' );
196+ print (
197+ 'Unexpected error in /data/[id].dart handler: $e \n $stackTrace ' ,
198+ );
123199 return Response (
124200 statusCode: HttpStatus .internalServerError,
125201 body: 'Internal Server Error.' ,
0 commit comments