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

new can-connect interface #304

Open
nlundquist opened this issue Jun 16, 2017 · 6 comments
Open

new can-connect interface #304

nlundquist opened this issue Jun 16, 2017 · 6 comments

Comments

@nlundquist
Copy link
Contributor

nlundquist commented Jun 16, 2017

With the rework currently being done to can-connect, we have an opportunity to redesign the interface to make usage with ES2015 classes easy as well as other ease of use improvements. This issue is intended to capture feedback on what users & other Bitovians would like to see in this new interface.

To kick off discussion we have several examples of potential redesigns:

1. Explicit Usage

  • this is comparable to what we have today, but requiring more emphasis on the user being exposed to how can-connect works behind the scenes
var baseConnection = require("can-connect/base/");
var combineRequests = require("can-connect/data/combine-requests/combine-requests")
var dataUrl = require("can-connect/data/url/url");

let connection = baseConnection({
  url: "/todos"
})
connection = dataUrl(connection)
connection = combineRequests(connection)
connection.init();

2. Class-based Usage

  • design behaviors to be usable as mixins on ES2015 classes
  • the behaviors could still be implemented to be usable as a plain function (rather than a mixin) on an instance of baseConnection (rather than a connection class constructor)
  • connection.init() is called implicitly by the TodoConnection constructor
@combineRequests
@dataUrl
class TodoConnection extends BaseConnection {
}

Todo.connection = new TodoConnection({
  url: "/todos"
})

3. Constructor Extend Usage

  • attach behaviors to a connection constructor rather than to an instance of a connection like approach 1
  • comparable to how we extend our can-constructor based constructors
// ES5
var TodoConnection = combineRequests(dataUrl(BaseConnection.extend("TodoConnection")));

Todo.connection = new TodoConnection({
  url: "/todos"
})

Any comments you might have on the above or any developer experience enhancements you'd like to see in the next interface are welcome!

@justinbmeyer
Copy link
Contributor

To be clear, we'd provide #3 for folks where ES6 trasnpiling isn't available right?

@matthewp
Copy link
Contributor

I'm guessing that combineRequests is a different thing in 2 and 3, right? Because I'm pretty sure the APIs are different. So those would be imported from different places.

Anyways, if you don't want to transpile or use babel plugins you could do it this way and it works in all modern browsers:

class TodoConnection extends combineRequests(dataUrl(BaseConnection)) {

}

Todo.connection = new TodoConnection({
  url: "/todos"
})

presumably this works with no extra effort, as extending classes and function constructors is the same.

@nlundquist
Copy link
Contributor Author

nlundquist commented Jun 16, 2017

@justinbmeyer that's right, no. 3 above would be the easier way of making the interface in no. 2 work in situations where transpiling is unavailable. we could plausibly make no. 1 the alternative interface where transpiling is unavailable but that would be harder.

I'd prefer the interface that Matthew suggest above, with classes, but without mixins, though it wouldn't work with any IE prior to Edge. I personally don't have a problem with making that restriction however and requiring ES6 transpiration for older IE.

@matthewp I believe a single behavior module would be able to support the usages in 2 & 3, though perhaps with a slightly different codepath between the usages, but I'd have to experiment to confirm that.

@nlundquist
Copy link
Contributor Author

In talking to a few Bitovians and external users, I've received unanimous support for approach no. 2.

I've also confirmed that approach no.3 and the approach suggested by Matthew could also be supported by the same behaviors with very little effort.

Going to move ahead with adding support for this API next week, updating our docs to show it as the first class usage, add an easily discoverable explanation of approach no.3 for those not using an ES6 transpiler and creating a guide.

@justinbmeyer
Copy link
Contributor

justinbmeyer commented Feb 8, 2018

@nlundquist How would #2 accept the Todo type? As follows?

@combineRequests
@dataUrl
class TodoConnection extends BaseConnection {
}

Todo.connection = new TodoConnection({
  url: "/todos",
  Map: Todo
})

@justinbmeyer
Copy link
Contributor

justinbmeyer commented Feb 8, 2018

It feels odd to extend a type without providing methods and then always create a singleton instance with it:

@realtime
class TodoConnection extends CanConnection {
  
}
new TodoConnection({
    service: todosService,
    Instance: Todo,
    Instances: TodoList
})

I wonder if there's a way to make these connections more useful for testing purpose. Maybe easier to mock-up behaviors?

@realtime
class TodoConnection extends CanConnection {
  Instance= Todo; // Using https://github.com/tc39/proposal-class-fields
  Instances = TodoList;
  Service: TodosService
}

new TodoConnection({
    service: todosService,
    Instance: Todo,
    Instances: TodoList
})
test("you can get data", function(){
  var connection = new TodoConnection({
    service: new FixtureService()
  });

  Todo.getList() //-> uses fixture service 

  connection.break() //-> removes all the `Todo` methods .. maybe restores them to what was there before?
})

An even crazier idea might be for new TodoConnection to actually return proxied versions of the Todo and TodoList constructor functions.

{Instance: Todo, Instances: TodoList} = new TodoConnection( {Instance: Todo, Instances: TodoList, service: mockService} );

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

No branches or pull requests

4 participants