Improve separation of concerns between core and backend libraries#453
Improve separation of concerns between core and backend libraries#453duckontheweb wants to merge 5 commits intoremove/backend-packagesfrom
Conversation
| @@ -1,3 +1,4 @@ | |||
| tests | |||
There was a problem hiding this comment.
This change is again not directly related to this refactor, but helped speed up the Docker builds
|
I like the approach of separating link injection from backend specific logic, my main concern here is breaking the client interfaces and adding extra boilerplate to the clients. I was thinking that instead of adding more methods we could handle this with a function in the API layer that is called in the FastAPI endpoint after each client method (ex. import typing
from starlette.requests import Request
from stac_fastapi.types.stac import Collection, Collections, Item, ItemCollection
StacTypes = typing.Union[Collection, Collections, Item, ItemCollection]
def hydrate_links(request: Request, data: StacTypes) -> StacTypes:
...The The route handler(s) would then look something like this: def _endpoint(
request: Request,
request_data: request_model
):
# Request data from the backend.
# Note that `Request` is no longer passed to client method.
backend_response = func(request_data)
# Hydrate links
response_with_links = hydrate_links(request, backend_response)
# Serialize response
return _wrap_response(response_with_links, response_class)A few advantages of this approach are:
We could probably also use FastAPI dependency injection here to simplify the code and make it easier to override, ref #402. For example the dependency could be a generic function/factory which returns the correct hydration function based on which endpoint is being called ( |
|
Circling back to this after thinking for a while, I think the most important thing for me is to remove the need to inject the starlette |
|
Thanks @geospatial-jeff, all of your points are right on. I'll update this PR to try to take more of this approach.
Yeah, I agree. I think the approach you outlined above would still break the client interfaces since they rely on the |
|
Closing as OBE #555. |
Related Issue(s):
Description:
Demonstrates one approach for creating a clearer separation of concerns between the core
stac-fastapipackage and the backend packages likestac-fastapi.pgstac. This draft targets the landing page and collections endpoints to demonstrate the approach; if we decide to go this route, we should apply this to all other route handlers as well.The general approach is as follows:
*BaseCoreClientclasses that are used directly as route handlers have been renamed with ahandle_prefix. These will be concrete methods defined in this library responsible for parsing the request, calling the appropriate backend method(s), and constructing the response.fetch_and are responsible for fetching the appropriate objects from the database or other backend. These methods have well-defined, typed inputs rather than accepting arbitrary**kwargs.This approach should make it easier to handle all of the logic around constructing links, conformance classes, and other API-layer concerns in this package, ensuring that responses are consistent across the different backends.
Some future TODOs:
fetch_andhandle_methods in separate classes or mixins. My preference for this draft was to focus on the functional changes and leave that kind of structural refactor to a later PR, but I can always experiment with changing the class structure if we decide we want that right away.I will open a PR in the
stac-fastapi-pgstacrepo to demonstrate the corresponding changes in that backend.EDIT: Note that this PR is against the
remove/backend-packagesbranch instead ofmasterto simplify the changes. Once #450 has been merged we can update this to usemasteras the base.PR Checklist:
pre-commit run --all-files)make test)make docs)