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

API consistency: property getters vs methods #280

Closed
ebidel opened this issue Aug 16, 2017 · 5 comments
Closed

API consistency: property getters vs methods #280

ebidel opened this issue Aug 16, 2017 · 5 comments
Labels

Comments

@ebidel
Copy link
Contributor

ebidel commented Aug 16, 2017

Conversation from #272 (comment). Some properties of the public API are exposed as methods:

  • browser.version()
  • page.protocolWSEndpoint(), page.url(), page.viewport()
  • frame.title(), frame.url(), frame.name()
  • ...

Others are properties:

  • page.mouse, page.tracing
  • dialog.type
  • request.url, request.url
  • response.url
  • ...

Q: Is there a reason all of these aren't ES5 getters? At the very least, we should be consistent across the API surface.

@ebidel ebidel changed the title API consistency: properties getters vs methods API consistency: property getters vs methods Aug 16, 2017
@JoelEinbinder
Copy link
Collaborator

browser.version() and frame.title() return promises and make trips through the protocol.

I'm fine with the others being getters. dialog.type is currently a property, but should probably be a getter.

page.viewport is a little bit weird because it has an asynchronous setter but a synchronous getter.

@aslushnikov
Copy link
Contributor

Q: Is there a reason all of these aren't ES5 getters?

We can't have everything as getters/setters since some of them are async.

we should be consistent across the API surface.

Agreed. Some time ago we decided on a simple rule to tell if something is a getter or a method:

Everything's a method, unless it's a "singleton" like page.mouse or page.keyboard.

  • it's easy to remember, both as library author and library client
  • as a library client, regardless of async nature of a method you can always await it if you're lazy to check docs
  • (from the experience with devtools codebase) methods are a pleasure to grep for, whereas grepping getters oftentimes yields a lot of noise. (e.g. .url might be a prefix to multiple things)

The rule is currently broken in a few places for different historic reasons, and we weren't proactive enough to fix it. E.g. Request/Response classes were modeled after the fetch api and inherited their getters (that's no longer a case).

If there are no objection to this codestyle, i'm happy to fix all the outliers.

@ebidel
Copy link
Contributor Author

ebidel commented Aug 16, 2017

Thanks for the explanation. Agreed that async calls should remain methods that return promises.

regardless of async nature of a method you can always await it if you're lazy to check docs

A nice side effect I hadn't thought of! I guess another reason to keep methods everywhere is for later when if/when we add chaining. Chaining methods is more natural.

we decided on a simple rule to tell if something is a getter or a method

@aslushnikov, can you drop that in at the top of the API docs if we're sticking with those rules?They'll be new to everyone else coming into the project :)

@ebidel
Copy link
Contributor Author

ebidel commented Dec 16, 2017

@aslushnikov can we bring this back, address API consistency for 1.0. Good first bug is fine.

The rule is currently broken in a few places for different historic reasons, and we weren't proactive enough to fix it. E.g. Request/Response classes were modeled after the fetch api and inherited their getters (that's no longer a case).

Yes please! Just ran into this again with Response.url. Everywhere else we use .url().

@aslushnikov
Copy link
Contributor

@ebidel sg!

@aslushnikov aslushnikov reopened this Dec 18, 2017
@aslushnikov aslushnikov added the P1 label Dec 18, 2017
aslushnikov added a commit to aslushnikov/puppeteer that referenced this issue Dec 19, 2017
The patch converts all the getters in the codebase into the methods.
For example, the `request.url` getter becomes the `request.url()`
method.

This is done in order to unify the API and make it more predictable.
The general rule for all further changes would be:
- there are no getters/fields exposed in the api
- the only exceptions are "namespaces", e.g. `page.keyboard`

Fixes puppeteer#280.

BREAKING CHANGE:
This patch ditches getters and replaces them with methods throughout
the API. The following methods were added instead of the fields:
- dialog.type()
- consoleMessage.args()
- consoleMessage.text()
- consoleMessage.type()
- request.headers()
- request.method()
- request.postData()
- request.resourceType()
- request.url()
- response.headers()
- response.ok()
- response.status()
- response.url()
aslushnikov added a commit that referenced this issue Dec 19, 2017
The patch converts all the getters in the codebase into the methods.
For example, the `request.url` getter becomes the `request.url()`
method.

This is done in order to unify the API and make it more predictable.
The general rule for all further changes would be:
- there are no getters/fields exposed in the api
- the only exceptions are "namespaces", e.g. `page.keyboard`

Fixes #280.

BREAKING CHANGE:
This patch ditches getters and replaces them with methods throughout
the API. The following methods were added instead of the fields:
- dialog.type()
- consoleMessage.args()
- consoleMessage.text()
- consoleMessage.type()
- request.headers()
- request.method()
- request.postData()
- request.resourceType()
- request.url()
- response.headers()
- response.ok()
- response.status()
- response.url()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants