-
Notifications
You must be signed in to change notification settings - Fork 3
VED-821 Refactor get by ID journey in line with cleaner design #868
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
Conversation
d8b7cf6 to
3cde49d
Compare
13e04f1 to
8c152ac
Compare
| def get_path_parameter(event: APIGatewayProxyEventV1, param_name: str) -> str: | ||
| return dict_utils.get_field( | ||
| dict(event), | ||
| "pathParameters", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor point but I don't love the "reflective" access of pathParameters (and headers below) as we don't really get the benefits of the type hints. What about:
return dict_utils.get_field(
event.pathParameters,
param_name,
default=""
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeh, that's fair. I'll look into it once I'm free.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| return None, None | ||
|
|
||
| def get_immunization_by_id(self, imms_id: str) -> Optional[dict]: | ||
| def get_immunization_by_id(self, imms_id: str) -> tuple[Optional[dict], Optional[str]]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think tuple is a less misleading return value than the previous dict, but I still had to read the last line to know what that tuple contained. Maybe something like get_immunisation_and_version_by_id would be clearer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, that sounds good. Had been thinking it might be better to have a single object that contains it, but it seems that the version is separate to the FHIR content and goes out as the header.
Will rename the function as such.
backend/src/service/fhir_service.py
Outdated
| return form_json(imms_resp, element, identifier, base_url) | ||
|
|
||
| def get_immunization_by_id(self, imms_id: str, supplier_system: str) -> Optional[dict]: | ||
| def get_immunization_by_id(self, imms_id: str, supplier_system: str) -> tuple[Immunization, str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same deal here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done for both.
| test_cases = { | ||
| ("Test UnauthorisedError", UnauthorizedError, 403, "forbidden", "Unauthorized request"), | ||
| ("Test UnauthorizedVaxError", UnauthorizedVaxError, 403, "forbidden", | ||
| "Unauthorized request for vaccine type"), | ||
| ("Test ResourceNotFoundError", ResourceNotFoundError, 404, "not-found", "Immunization resource does not " | ||
| "exist. ID: 123") | ||
| } | ||
|
|
||
| for msg, error_type, expected_status, expected_code, expected_message in test_cases: | ||
| with self.subTest(msg=msg): | ||
|
|
||
| @fhir_api_exception_handler | ||
| def dummy_func(): | ||
| if msg == "Test ResourceNotFoundError": | ||
| raise error_type(resource_type="Immunization", resource_id="123") | ||
|
|
||
| raise error_type() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could provide the exact error to raise in the test case, then we wouldn't need the msg logic:
| test_cases = { | |
| ("Test UnauthorisedError", UnauthorizedError, 403, "forbidden", "Unauthorized request"), | |
| ("Test UnauthorizedVaxError", UnauthorizedVaxError, 403, "forbidden", | |
| "Unauthorized request for vaccine type"), | |
| ("Test ResourceNotFoundError", ResourceNotFoundError, 404, "not-found", "Immunization resource does not " | |
| "exist. ID: 123") | |
| } | |
| for msg, error_type, expected_status, expected_code, expected_message in test_cases: | |
| with self.subTest(msg=msg): | |
| @fhir_api_exception_handler | |
| def dummy_func(): | |
| if msg == "Test ResourceNotFoundError": | |
| raise error_type(resource_type="Immunization", resource_id="123") | |
| raise error_type() | |
| test_cases = { | |
| (UnauthorizedError(), 403, "forbidden", "Unauthorized request"), | |
| (UnauthorizedVaxError(), 403, "forbidden", "Unauthorized request for vaccine type"), | |
| ( | |
| ResourceNotFoundError(resource_type="Immunization", resource_id="123"), | |
| 404, | |
| "not-found", | |
| "Immunization resource does not exist. ID: 123" | |
| ) | |
| } | |
| for error, expected_status, expected_code, expected_message in test_cases: | |
| with self.subTest(msg=f`Test {error.__class__.__name__}`): | |
| @fhir_api_exception_handler | |
| def dummy_func(): | |
| raise error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done - much nicer.
|



Summary
Refactors the Get by ID journey to use the Controller -> Service -> Repository pattern properly. As this is quite a simple endpoint, I have also made quite a number of additional changes to show how I would like us to begin structuring the API code.
Changes:
Reviews Required
Review Checklist
ℹ️ This section is to be filled in by the reviewer.