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

Expand fs-ts in Prism's router #402

Merged
merged 14 commits into from Jul 9, 2019
Merged

Expand fs-ts in Prism's router #402

merged 14 commits into from Jul 9, 2019

Conversation

XVincentX
Copy link
Contributor

@XVincentX XVincentX commented Jul 6, 2019

The following PR extends the usage of fp-ts to the routing package as well by basically making sure it does not throw exceptions anymore, but rather use the Either object to express an error object.

With this — the router and the mocker finally compose because the type match (they both return an Either<Error, T>.

Extend the Either usage to the router was indeed the easy part: https://github.com/stoplightio/prism/pull/402/files#diff-f9a10b37616fb5669ecd5218fc8535c9L16

The problem started when I started to integrate and try to compose the new function in the mega-file-to-split:

  1. The whole flow is sync apart from the edge case when we need to employ the forwarder, and this requires an additional abstraction layer
    https://github.com/stoplightio/prism/pull/402/files#diff-47c5dc2d65fd624c869f5f08d0cfb56aR45

  2. What's really preventing from having a clean and functional flow is the validation process that's basically creating an empty array, giving it to the mocker and expecting to receive a filled array. This forces me to keep some stuff here and some stuff there; if the mocker could just return the validations, that'd improve the code a lot.

  3. In order to keep the API compatible with what we have, I have to do some wrapping I'd like to avoid
    https://github.com/stoplightio/prism/pull/402/files#diff-47c5dc2d65fd624c869f5f08d0cfb56aR98


That said, the funny thing is that, although this Pull Request is meant to be an improvement, you can argue that the code is effectively uglier than it is. (Well I do not think it is, but you mileage may vary)

The good news though is that — I'm not sure if you remember, we were discussing on how to refactor this part and nobody (me included) really came up with good ideas.

By trying to extend the functional parts to the router — I now know exactly what needs to be done and how to move forward. This is freaking awesome, to be honest.

@XVincentX XVincentX force-pushed the feat/fp-ts-router branch 2 times, most recently from 1e0ff9f to 9f3aced Compare July 7, 2019 07:28
@XVincentX XVincentX marked this pull request as ready for review July 7, 2019 07:30
Copy link
Contributor

@karol-maciaszek karol-maciaszek left a comment

Choose a reason for hiding this comment

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

I can admit that it takes some time to see the goal (and what those tons of helper functions do).

I've put some questions and comments.

One general note: the code looks complicated because it is long and deeply nested. How about enclosing parts into descriptive functions, so a human can see the overall flow and can dig into details if needed.

Sth like:

router.route()
.fold(modyfingSomehowLeftAndRight)
.chain(doingSthUnderstandableToLeftAndRight)
...

Second thing: Either.getValidation pattern seems to fit better here?

const { message, name, status } = error as ProblemJsonError;
// otherwise let's just stack it on the inputValidations
// when someone simply wants to hit an URL, don't block them
inputValidations.push({
Copy link
Contributor

Choose a reason for hiding this comment

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

Pushing things to array which is defined outside function chains feels not right. How about using validations? (https://dev.to/gcanti/getting-started-with-fp-ts-either-vs-validation-5eja - Validation section in the middle)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes! That's exactly what I wanted to do. However I'm proceeding with baby steps here as — you've probably noticed — it's hard to digest all in one place; moreover we're close to the release and I didn't want to change that many things at the time.

…but yes it's exactly the direction I want to take!

},
defaultComponents.mocker,
value => right2v(value),
Copy link
Contributor

Choose a reason for hiding this comment

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

I had a problem finding documentation for right2v. Isn't it deprecated?

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 is deprecated in 2.x — Prism is currently on 1.9. I'll migrate it soon though.

packages/core/src/factory.ts Outdated Show resolved Hide resolved
@XVincentX
Copy link
Contributor Author

One general note: the code looks complicated because it is long and deeply nested. How about enclosing parts into descriptive functions, so a human can see the overall flow and can dig into details if needed.

Yeah I will probably try again — I gave up because every function was taking something like 3000 parameters complicating the thing anyway. I'm willing to give it another try though.

Thanks for the review!

@XVincentX XVincentX self-assigned this Jul 9, 2019

expect(response.statusCode).toBe(200);
});
test.todo(
Copy link
Contributor

Choose a reason for hiding this comment

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

Such a decent test :( why remove 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.

It was skipped — I'm fine putting it back but it's not getting executed anyway. I'd rather see a todo that says "Hey write this" instead of a skip that you do not easily see

}),
).rejects.toThrowError(ProblemJsonError.fromTemplate(UNPROCESSABLE_ENTITY));
});
test.todo('with invalid body returns validation errors');
Copy link
Contributor

Choose a reason for hiding this comment

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

🔥 🔥 🔥 You're removing my lovely tests :( 🔥

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 was skipped — I'm fine putting it back but it's not getting executed anyway. I'd rather see a todo that says "Hey write this" instead of a skip that you do not easily see

resource,
input: { validations: { input: inputValidations }, data: input },
config: configObj,
return right2v<Error, Resource | undefined>(undefined);
Copy link
Contributor

Choose a reason for hiding this comment

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

right2v, whoa what a lovely interface :P I have a suggestion
right2lolz because why not? Ok enough sarcazm for today

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 actually a good point — it has been fixed in 2.x but I didn't want to deal with breaking changes right now.

Copy link
Contributor

Choose a reason for hiding this comment

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

We'll get less PR from random people. Entry threshold is set high ;)

Copy link
Contributor

@chris-miaskowski chris-miaskowski left a comment

Choose a reason for hiding this comment

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

Ok, so all the "code style" related comments aside I think it's a very decent change and good step forward.
But I take your word on the Lunch & Learns @XVincentX ! :P

@XVincentX XVincentX merged commit 555d3f0 into master Jul 9, 2019
@XVincentX XVincentX deleted the feat/fp-ts-router branch July 9, 2019 14:07
@philsturgeon
Copy link
Collaborator

philsturgeon commented Jul 9, 2019 via email

@XVincentX
Copy link
Contributor Author

@philsturgeon

Just to clarify — the tests haven't been removed; I've just moved them from test.skip to ´test.todo´. I also left the comments.

The current implementation there wasn't useful anyway and just gave the impression that the test was done. Now we can clearly see that the test is not done, and we'll fix that in the future.

@philsturgeon
Copy link
Collaborator

philsturgeon commented Jul 9, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants