-
Notifications
You must be signed in to change notification settings - Fork 102
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
Improve separation of concerns between core and backend libraries #453
Improve separation of concerns between core and backend libraries #453
Conversation
@@ -1,3 +1,4 @@ | |||
tests |
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.
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-fastapi
package 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:
*BaseCoreClient
classes 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-pgstac
repo to demonstrate the corresponding changes in that backend.EDIT: Note that this PR is against the
remove/backend-packages
branch instead ofmaster
to simplify the changes. Once #450 has been merged we can update this to usemaster
as the base.PR Checklist:
pre-commit run --all-files
)make test
)make docs
)