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

Make routes in back-end comply to Open Closed Principle #4859

Merged
merged 40 commits into from
Mar 11, 2022
Merged

Conversation

jansav
Copy link
Contributor

@jansav jansav commented Feb 14, 2022

Motivation:

  • I should be able to add route with minimal modifications (none)
  • Route should have it's own dependencies
  • Route shouldn't be responsible of e.g. error handling which can be abstracted to higher level.

Solution:

Introduce routeInjectionToken which any back-end route can implement by adding injectionToken: routeInjectionToken. Any injectable implementing said injectionToken will be registered automatically.

Note: base-branch is PR #4842 so let's get that merged first.

TBD later:

  1. Get rid of IncomingMessage and http.ServerResponse interface from router so that new routes can be unit tested easily even when using router in tests.

@jansav jansav added the chore label Feb 14, 2022
@jansav jansav added this to the 5.5.0 milestone Feb 14, 2022
@jansav jansav requested a review from a team as a code owner February 14, 2022 10:15
@jansav jansav requested review from jweak and Iku-turso and removed request for a team February 14, 2022 10:15
@github-actions
Copy link
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions
Copy link
Contributor

Conflicts have been resolved. A maintainer will review the pull request shortly.

ixrock
ixrock previously approved these changes Feb 23, 2022
Copy link
Contributor

@ixrock ixrock left a comment

Choose a reason for hiding this comment

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

Didn't run the app, but code LGTM.

import logger from "./logger";
import type { LensApiResultContentType } from "./router-content-types";
import { contentTypes } from "./router-content-types";
import "../common/vars";
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need import whole package without using anything locally from it?

Copy link
Contributor Author

@jansav jansav Feb 25, 2022

Choose a reason for hiding this comment

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

My question exactly... There is side-effect in common/vars which defines __static and therefore is required. Something that is of course wrong, but out of scope in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe add comment/todo so that next reader knows why it's there?

src/main/routes/static-file-route.injectable.ts Outdated Show resolved Hide resolved
@@ -326,6 +326,7 @@
"@typescript-eslint/eslint-plugin": "^5.10.1",
"@typescript-eslint/parser": "^5.10.1",
"ansi_up": "^5.1.0",
"mock-http": "^1.1.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need this package / extra dependency? Can we live without it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At the moment, no.

Get rid of IncomingMessage and http.ServerResponse interface from router so that new routes can be unit tested easily even when using router in tests.

However, we can after this.

@@ -108,7 +108,7 @@ export async function upgradeRelease(name: string, chart: string, values: any, n

return {
log: output,
release: getRelease(name, namespace, kubeconfigPath, kubectlPath),
release: await getRelease(name, namespace, kubeconfigPath, kubectlPath),
Copy link
Contributor

Choose a reason for hiding this comment

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

Noticed no catch in this try...finally, will await getRelease throw? Or error is caught and handled somewhere else?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Key difference here is that all back-end API responds go through same place which already catches fatal errors. That being said, if it fails fatally, API call is resolved with status code 422 and error message. And in this case, there is no non-fatal error to be handled. Goal is to get rid of try-catches in operational code for good (strategic places that handle errors for everything to allow error monitoring etc). Throwing is mechanism that is reserved for fatal errors which should prevent code to be executed and for non fatal errors we have better alternatives.

Base automatically changed from update-injectable to master February 25, 2022 16:10
@github-actions
Copy link
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions
Copy link
Contributor

Conflicts have been resolved. A maintainer will review the pull request shortly.

@github-actions
Copy link
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 3, 2022

Conflicts have been resolved. A maintainer will review the pull request shortly.

Iku-turso
Iku-turso previously approved these changes Mar 3, 2022
src/main/router-content-types.ts Outdated Show resolved Hide resolved
src/main/router-content-types.ts Outdated Show resolved Hide resolved
src/main/router-content-types.ts Outdated Show resolved Hide resolved
src/main/router.test.ts Outdated Show resolved Hide resolved
interface Dependencies {
routePortForward: (request: LensApiRequest) => Promise<void>;
parseRequest: (request: http.IncomingMessage, _: null, options: { parse: boolean; output: string }) => Promise<{ payload: any }>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

why even have the second param?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's third-party library.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah but we can wrap it if we want

src/main/router.ts Outdated Show resolved Hide resolved
writeServerResponse(mappedResult);
};

const writeServerResponseFor =
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit, all this extra whitespace makes it harder to read. Could this be a normal function or at least add some ()?


instantiate: (): Route<GetChartResponse> => ({
method: "get",
path: `${apiPrefix}/v2/charts/{repo}/{chart}`,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I have (what I think) is a pretty cool idea of how to make sure that this string is "correctly typed" with regards to the interface that Params expects below but we can do that later.

jansav added 22 commits March 11, 2022 08:55
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
…t interesting

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
@github-actions
Copy link
Contributor

Conflicts have been resolved. A maintainer will review the pull request shortly.

Copy link
Contributor

@jakolehm jakolehm left a comment

Choose a reason for hiding this comment

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

LGTM

@jansav jansav merged commit 38af26e into master Mar 11, 2022
@jansav jansav deleted the back-end-routes branch March 11, 2022 10:20
@Nokel81 Nokel81 mentioned this pull request May 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants