Skip to content
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

refactor: add pipeline concept #8020

Merged
merged 3 commits into from
Aug 10, 2023
Merged

refactor: add pipeline concept #8020

merged 3 commits into from
Aug 10, 2023

Conversation

ematipico
Copy link
Member

Changes

This PR starts the refactors around how routes are rendered.

The idea is the following: creating a "core" that does one single thing, render a route by returning a Response, and remove from the equation all the information that aren't part of a page. For example, the Environment is not information that belongs exclusively to a page.

Then, in the future refactos, we are going to create specialized pipelines - or consumers - that compute the basic information in a different way, and then handle the finished Response in a different way. These specialized pipelines will be: the dev server, the build, SSR. In the future we will have containers and testing.

We are going to have a Pipeline base class, which exposes a method called renderRoute. It accepts the RenderContext and the ComponentInstance and returns a Response. Very simple.

In this PR I created the first consumer, AKA SSRRoutePipeline. As you might have noticed, some logic was moved inside this new class.

In order to make the internal developments better, I marked route inside RenderContext mandatory. The reason why I did so is because RouteData is supposed to contain the information of the type of the route we're about to render, but since could be undefined, we ended up having an API like this:

tryRenderRoute('page', renderContext)

Which doesn't make much sense, because we're supposed to have the route already inside renderContext. I marked it mandatory, and the majority of the tests still pass, which means that the change in logic is correct.

Testing

The existing tests should pass. I updated the tests where we create the RenderContext manually, because now route is mandatory. The shape of route used in tests won't trigger the function calls callGetStaticPaths, which isn't needed in those tests.

Docs

/cc @withastro/maintainers-docs for feedback!

@changeset-bot
Copy link

changeset-bot bot commented Aug 10, 2023

⚠️ No Changeset found

Latest commit: 2a43c80

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions bot added the pkg: astro Related to the core `astro` package (scope) label Aug 10, 2023
@@ -184,35 +184,8 @@ export class App {
}
Reflect.set(response, responseSentSymbol, true);
return response;
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, love all of this deletion

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, all this cleanup in the App is great!

@matthewp
Copy link
Contributor

Looks great! Is the plan to later add a build pipeline and a dev pipeline?

@ematipico
Copy link
Member Author

Looks great! Is the plan to later add a build pipeline and a dev pipeline?

Yes. It's possible that we would add more "core functions" , or maybe not.

So I want to make the changes slow and steady, so we get comfortable with the new flow of data and document things.

@ematipico ematipico requested a review from a team as a code owner August 10, 2023 13:43
Copy link
Member

@natemoo-re natemoo-re left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Excited to see how this centralizes our logic across different targets!

@@ -184,35 +184,8 @@ export class App {
}
Reflect.set(response, responseSentSymbol, true);
return response;
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, all this cleanup in the App is great!

@ematipico ematipico merged commit a39ff7e into next Aug 10, 2023
@ematipico ematipico deleted the feat/pipeline-plt-762 branch August 10, 2023 13:56
Comment on lines +26 to +31
onRequest?: MiddlewareEndpointHandler;
/**
* The handler accepts the *original* `Request` and result returned by the endpoint.
* It must return a `Response`.
*/
endpointHandler?: EndpointResultHandler;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we prefix these with # or mark them protected/private so we don't expose them?

}

export class SSRRoutePipeline extends Pipeline {
encoder = new TextEncoder();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe this could be private too.

Comment on lines +23 to +27
this.setEndpointHandler(this.#ssrEndpointHandler);
}

// This function is responsible for handling the result coming from an endpoint.
async #ssrEndpointHandler(request: Request, response: EndpointCallResult): Promise<Response> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit: Is this.setEndpointHandler and this.#ssrEndpointHandler something that every extended class of Pipeline needs to implement? I was thinking we can create an abstract method like abstract endpointHandler() in Pipeline instead, but I'm also fine with this pattern if you're still shaping up the final pattern.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, no.

Not all the future pipelines will have to handle endpoints. For example: a testing pipeline will need to be used only when needed, an Astro container won't need it (I presume)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: astro Related to the core `astro` package (scope)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants