Skip to content

Commit

Permalink
fix: change PUT behavior to return 404 when resource not found
Browse files Browse the repository at this point in the history
  Modified the behavior of the PUT verb in the REST service to return an HTTP 404 (Not Found) status when a resource with the specified ID is not found. Previously, if a resource with the specified ID was not found, the system would create a new resource and return an HTTP 200 (OK) status. This change aligns the service with REST best practices, ensuring that API consumers receive clear feedback when attempting to update a non-existent resource.
  • Loading branch information
rodrigorahman committed Feb 20, 2024
1 parent 5ec8c82 commit c97c6bd
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2.0.6
fix: change PUT behavior to return 404 when resource not found

Modified the behavior of the PUT verb in the REST service to return an HTTP 404 (Not Found) status when a resource with the specified ID is not found. Previously, if a resource with the specified ID was not found, the system would create a new resource and return an HTTP 200 (OK) status. This change aligns the service with REST best practices, ensuring that API consumers receive clear feedback when attempting to update a non-existent resource.


## 2.0.5
fix: Change form that get local ip address

Expand Down
3 changes: 3 additions & 0 deletions lib/src/core/exceptions/resource_notfound_exception.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
final class ResourceNotfoundException implements Exception {

}
16 changes: 16 additions & 0 deletions lib/src/repositories/database_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:io';

import 'package:json_rest_server/src/core/enum/id_type_enum.dart';
import 'package:json_rest_server/src/core/exceptions/conflict_id_exception.dart';
import 'package:json_rest_server/src/core/exceptions/resource_notfound_exception.dart';
import 'package:json_rest_server/src/models/config_model.dart';
import 'package:uuid/uuid.dart';

Expand Down Expand Up @@ -32,6 +33,21 @@ class DatabaseRepository {
Map<String, dynamic> getById(String table, dynamic id) => getAll(table)
.firstWhere((element) => element['id'] == id, orElse: () => {});

Map<String, dynamic>? update(String table, Map<String, dynamic> data) {
final {'id': id} = data;

if (id == null) {
throw ResourceNotfoundException();
}
final lineData = getById(table, id);

if (lineData.isEmpty) {
throw ResourceNotfoundException();
}

return save(table, data);
}

Map<String, dynamic>? save(String table, Map<String, dynamic> data) {
final id = data['id'];
var saveData = <String, dynamic>{};
Expand Down
9 changes: 9 additions & 0 deletions lib/src/server/handler_request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'dart:io';
import 'package:get_it/get_it.dart';
import 'package:json_rest_server/src/core/broadcast/broadcast_controller.dart';
import 'package:json_rest_server/src/core/exceptions/conflict_id_exception.dart';
import 'package:json_rest_server/src/core/exceptions/resource_notfound_exception.dart';
import 'package:json_rest_server/src/core/helper/cors_helper.dart';
import 'package:json_rest_server/src/models/broadcast_model.dart';
import 'package:json_rest_server/src/models/config_model.dart';
Expand Down Expand Up @@ -102,6 +103,14 @@ class HandlerRequest {
),
headers: jsonHelper.jsonReturn,
);
} on ResourceNotfoundException catch (e, s) {
log('Resource not found', error: e, stackTrace: s);
return Response.notFound(
jsonEncode(
{'erro': 'resource not found'},
),
headers: jsonHelper.jsonReturn,
);
} catch (e, s) {
log('Erro interno', error: e, stackTrace: s);
return Response.internalServerError(
Expand Down
2 changes: 1 addition & 1 deletion lib/src/server/handlers/put_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class PutHandler {
}
final dataUpdate = jsonDecode(body);
dataUpdate['id'] = int.tryParse(id) ?? id;
return _databaseRepository.save(table, dataUpdate);
return _databaseRepository.update(table, dataUpdate);
}

return null;
Expand Down
11 changes: 3 additions & 8 deletions test/server/handlers/get_handler_test.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import 'package:dio/dio.dart';
import 'package:json_rest_server/src/server/core/env.dart';
import 'package:json_rest_server/src/server/json_rest_server.dart';
import 'package:test/test.dart';
import 'package:path/path.dart' as path;

class EnvMock extends Env {
@override
String get debugPath {
return '${path.join(path.current, 'test', 'server', 'server_config')}${path.separator}';
}
}
import '../mock/env_mock.dart';



void main() {
group('Getter Tests', () {
Expand Down
52 changes: 52 additions & 0 deletions test/server/handlers/put_handler_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import 'package:dio/dio.dart';
import 'package:json_rest_server/src/server/json_rest_server.dart';
import 'package:test/test.dart';

import '../mock/env_mock.dart';
import 'get_handler_test.dart';

void main() {
group('Put Tests group', () {
setUpAll(() async => await JsonRestServer(EnvMock()).startServer());

test('Should update data', () async {
final Response(data: {'id': testID}, statusCode: insertStatusCode) =
await Dio().post(
'http://localhost:8080/tests/',
data: {"name": "Teste shoud update"},
);

expect(insertStatusCode, equals(200));

final Response(statusCode: updateStatus) = await Dio().put(
'http://localhost:8080/tests/$testID',
data: {"name": "Teste shoud updated"},
);

expect(updateStatus, equals(200));

final Response(data: {'name': nameTest}) = await Dio().get(
'http://localhost:8080/tests/$testID',
);

expect(nameTest, equals('Teste shoud updated'));

await Dio().delete(
'http://localhost:8080/tests/$testID',
);
});

test('Should error 404', () async {
try {
await Dio().put(
'http://localhost:8080/tests/123',
data: {"name": "Teste shoud updated"},
);
} on DioException catch (e) {
expect(e.response?.statusCode, equals(404));
}


});
});
}
9 changes: 9 additions & 0 deletions test/server/mock/env_mock.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'package:json_rest_server/src/server/core/env.dart';
import 'package:path/path.dart' as path;

class EnvMock extends Env {
@override
String get debugPath {
return '${path.join(path.current, 'test', 'server', 'server_config')}${path.separator}';
}
}
2 changes: 1 addition & 1 deletion test/server/server_config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ database: database.json
enableSocket: true
socketPort: 8081
broadcastProvider: socket #socket,slack or only socket or only slack
idType: int
idType: uuid
slack:
slackUrl: '' #your webhook url from slack
slackChannel: '' #your channel starting with #
Expand Down
145 changes: 144 additions & 1 deletion test/server/server_config/database.json
Original file line number Diff line number Diff line change
@@ -1 +1,144 @@
{"users":[{"id":"67256120-0258-1e7b-8d18-87b1c7869e63","email":"at1@gmail.com","password":"123123"},{"id":"d51a7d90-4296-1e8a-877a-b36fd069fb19","email":"at1@gmail.com","password":"123123"}],"adm_users":[{"id":"024fb8e0-02fd-1e7b-8d18-87b1c7869e63","email":"terminal1@gmail.com","password":"123123"}],"attendantDeskAssignment":[],"patients":[{"id":"93b3fd10-9dd7-1e82-bfae-fb5426cd6532","name":"Rodrigo Rahman 2","email":"rodrigorahman@academiadoflutter.com.br","phone_number":"(11) 1231212312","document":"123.123.123-12","address":{"cep":"09190390","street_address":"Rua X","number":"51","address_complement":"","state":"SP","city":"Santo André","district":"Jardins"},"guardian":"","guardian_identification_number":""},{"id":"64a62430-4df9-1e83-bfae-fb5426cd6532","name":"teste","email":"teste@teste.com.br","phone_number":"(12) 3123-1231","document":"321.321.321-32","address":{"cep":"11.111-111","street_address":"teste","number":"12","address_complement":"teste","state":"teste","city":"teste","district":"teste"},"guardian":"teste","guardian_identification_number":"123.123.123-13"}],"patientInformationForm":[],"painelCheckin":[],"tests":[{"id":"3b2526a7-96ad-4884-8d89-aac3a8f8d1e1","name":"Endoscopia"},{"id":"89b5ecf8-dcdd-42fd-b1ec-335537b661cc","name":"Exame de Sangue"},{"id":"4c7c2c0e-84fa-4b91-aff1-f8f9a99b4925","name":"Ressonância Magnética"},{"id":"49d4cb2e-afd5-4345-ac03-92ec451c0601","name":"Tomografia Computadorizada"},{"id":"0c4f178f-8b57-4f03-bbd5-5463e228d810","name":"Ultrassonografia"},{"id":"56ec8065-417f-4082-bcb5-1900b504c78d","name":"Eletrocardiograma"},{"id":"fb685fbd-853e-49f2-8a55-1086d08db53e","name":"Raio-X"},{"id":"93d3d43a-2f14-4d00-984b-d46f35c76142","name":"Colonoscopia"},{"id":"957a344b-ec07-4023-8e51-1adfa4e62a05","name":"Teste de Esforço"},{"id":"98b881bc-67cf-4e10-adca-17a1f59d798e","name":"Biopsia"},{"id":"9a4a3733-50cf-47ca-a671-2fbadd319d5b","name":"Eletroencefalograma"},{"id":"222fd2b7-af4e-42e2-8f08-069cbcd0f728","name":"Exame de Urina"},{"id":"590f8160-7920-40f7-9f44-cc6d42dff46d","name":"Holter 24 Horas"},{"id":"c71c2048-0cb8-49a2-a4f2-3b0dcdee6dd6","name":"Mamografia"},{"id":"05a0f0fb-6202-420a-8644-a1c1772c9da6","name":"Densitometria Óssea"},{"id":"2b029e96-eb37-43ad-8475-2d5cd273ef7e","name":"Teste de Gravidez"},{"id":"c0537924-ef52-43f9-8819-1f2a730eb5b7","name":"Teste de Glicemia"},{"id":"0fb498bd-2a27-4c23-9cf4-87b8a633d218","name":"Esprometria"},{"id":"67397c75-6ec4-4699-b52c-dadeb44b4734","name":"Audiometria"},{"id":"09835021-acc2-4792-a167-46d067de7406","name":"Exame de Vista"}]}
{
"users": [
{
"id": "67256120-0258-1e7b-8d18-87b1c7869e63",
"email": "at1@gmail.com",
"password": "123123"
},
{
"id": "d51a7d90-4296-1e8a-877a-b36fd069fb19",
"email": "at1@gmail.com",
"password": "123123"
}
],
"adm_users": [
{
"id": "024fb8e0-02fd-1e7b-8d18-87b1c7869e63",
"email": "terminal1@gmail.com",
"password": "123123"
}
],
"attendantDeskAssignment": [],
"patients": [
{
"id": "93b3fd10-9dd7-1e82-bfae-fb5426cd6532",
"name": "Rodrigo Rahman 2",
"email": "rodrigorahman@academiadoflutter.com.br",
"phone_number": "(11) 1231212312",
"document": "123.123.123-12",
"address": {
"cep": "09190390",
"street_address": "Rua X",
"number": "51",
"address_complement": "",
"state": "SP",
"city": "Santo André",
"district": "Jardins"
},
"guardian": "",
"guardian_identification_number": ""
},
{
"id": "64a62430-4df9-1e83-bfae-fb5426cd6532",
"name": "teste",
"email": "teste@teste.com.br",
"phone_number": "(12) 3123-1231",
"document": "321.321.321-32",
"address": {
"cep": "11.111-111",
"street_address": "teste",
"number": "12",
"address_complement": "teste",
"state": "teste",
"city": "teste",
"district": "teste"
},
"guardian": "teste",
"guardian_identification_number": "123.123.123-13"
}
],
"patientInformationForm": [],
"painelCheckin": [],
"tests": [
{
"id": "3b2526a7-96ad-4884-8d89-aac3a8f8d1e1",
"name": "Endoscopia"
},
{
"id": "89b5ecf8-dcdd-42fd-b1ec-335537b661cc",
"name": "Exame de Sangue"
},
{
"id": "4c7c2c0e-84fa-4b91-aff1-f8f9a99b4925",
"name": "Ressonância Magnética"
},
{
"id": "49d4cb2e-afd5-4345-ac03-92ec451c0601",
"name": "Tomografia Computadorizada"
},
{
"id": "0c4f178f-8b57-4f03-bbd5-5463e228d810",
"name": "Ultrassonografia"
},
{
"id": "56ec8065-417f-4082-bcb5-1900b504c78d",
"name": "Eletrocardiograma"
},
{
"id": "fb685fbd-853e-49f2-8a55-1086d08db53e",
"name": "Raio-X"
},
{
"id": "93d3d43a-2f14-4d00-984b-d46f35c76142",
"name": "Colonoscopia"
},
{
"id": "957a344b-ec07-4023-8e51-1adfa4e62a05",
"name": "Teste de Esforço"
},
{
"id": "98b881bc-67cf-4e10-adca-17a1f59d798e",
"name": "Biopsia"
},
{
"id": "9a4a3733-50cf-47ca-a671-2fbadd319d5b",
"name": "Eletroencefalograma"
},
{
"id": "222fd2b7-af4e-42e2-8f08-069cbcd0f728",
"name": "Exame de Urina"
},
{
"id": "590f8160-7920-40f7-9f44-cc6d42dff46d",
"name": "Holter 24 Horas"
},
{
"id": "c71c2048-0cb8-49a2-a4f2-3b0dcdee6dd6",
"name": "Mamografia"
},
{
"id": "05a0f0fb-6202-420a-8644-a1c1772c9da6",
"name": "Densitometria Óssea"
},
{
"id": "2b029e96-eb37-43ad-8475-2d5cd273ef7e",
"name": "Teste de Gravidez"
},
{
"id": "c0537924-ef52-43f9-8819-1f2a730eb5b7",
"name": "Teste de Glicemia"
},
{
"id": "0fb498bd-2a27-4c23-9cf4-87b8a633d218",
"name": "Esprometria"
},
{
"id": "67397c75-6ec4-4699-b52c-dadeb44b4734",
"name": "Audiometria"
},
{
"id": "09835021-acc2-4792-a167-46d067de7406",
"name": "Exame de Vista"
}
]
}

0 comments on commit c97c6bd

Please sign in to comment.