owncloud / core

:cloud: ownCloud web server core (Files, DAV, etc.)
https://owncloud.com
GNU Affero General Public License v3.0
8.37k stars 2.06k forks source link

Public Chat API #11607

Closed LEDfan closed 10 years ago

LEDfan commented 10 years ago

With the Chat app it's possible to create your own Chat backend. IMO this API should be in core, since this is the case for all apps and there can't be any app dependency. When this won't be in core and someone want's to create a custom Chat backend this code should be placed into the Chat app and this has a lot of problems.

Design of the API

I think an interface called \OCP\Chat\IBackend should be created. This interface would hold all the information needed for the \OCP\Chat\BackendsManager to register the backend. In theroy then every app could use the backend information. But in real life only the Chat app would use this information. To register a backend an app should implement the IBackend interface and register it \OCP\Chat\BackendsManager::register(IBackend $backend). The Chat app fetches the information when the Chat app is loaded \OCP\Chat\BackendsManager::getBackends(). All $backend objects will be returned. This then can be used for the bootstraping the Chat client. (i.e. the JS code inside the Chat app). A Chat backend app would also need to register JS code. An Angular factory will be used for this. (And thus Angular's dependency injection) This should be done in the appinfo\app.php file. The JS could should only be registered when the chat app is loaded. (Note that Angular won't be loaded by core nor on every request)

Goal of the Chat app

The Chat app keeps existing of course and will provide:

What do you think about this? cc @jancborchardt @Raydiation @PVince81 @DeepDiver1975

EDIT: if you agree with this, I'll write the code :smiley:

BernhardPosselt commented 10 years ago

I think this should go inside the chat app. If someone wants to build an XMPP backend, he should write one inside the chat app. Apart from that its easy to test if the chat app is enabled and then require the interface

PVince81 commented 10 years ago

Ideally there should be a mechanism where an app like the chat app can register interfaces. The chat app itself would register a "chat backend" interface service.

Then other apps would register "chat backend providers" with their own implementation. Then the chat app needs a method to query all registered "chat backend providers".

Not sure whether such abstract mechanism already exists in core ? @icewind1991 @bantu

BernhardPosselt commented 10 years ago

Basically:

if (\OCP\App::isEnabled('chat')) {
   // code here
}

News does it in the same way

LEDfan commented 10 years ago

If someone wants to build an XMPP backend, he should write one inside the chat app.

Of course a main used chat backend should go in the Chat app. But what if someone (e.g. a company) want's to implments it's own Chat backend for theire internal chat service? If they would put the code inside the Chat app they can't pull upstream changes etc

It would be possible to put the IBackend and BackendsManager inside the Chat app. But this isn't the case for the Contacts app, the Calendar app etc.. There will be an app dependency

BernhardPosselt commented 10 years ago

I actually have no idea why there are backends built into core for contacts and calendar :P (if there are)

And yes, there will be an app dependency but such is the way of things :) That's why we should actually include a way to at least do a soft check for those on installation like

chat backend

requires:

LEDfan commented 10 years ago

I actually have no idea why there are backends built into core for contacts and calendar :P (if there are)

Yes this is. And it was very welcome for exposing the ownCloud users as contacts. https://github.com/owncloud/core/blob/master/lib/private/contacts/localaddressbook.php

In the first place there won't be a chat backend in core.

BernhardPosselt commented 10 years ago

I mean there are two ways:

I don't think the first choice is the way to go since core is developed by the company which has limitted resources.

DeepDiver1975 commented 10 years ago

What we basically need in core are the interfaces which are used as communication protocols between apps.

The core (the public apis hosted in core) will act as a mediator between apps which want to expose functionality and apps which want to consume these functionalities.

This also the reason why the current public apis have that manager interface where multiple backends can be registered and consumed.

A call like if (\OCP\App::isEnabled('chat')) is so wrong! As a consumer I don't care if chat, super-chat or marvelous-chat apps or all of them are enabled - all I want is way to see who is online and who can I send a message to.

Maybe even the mail app one day could export a chat backend and we will chat via email?

This is the basic design principle behind the ownCloud public api.

LEDfan commented 10 years ago

@DeepDiver1975 I agree :)

Maybe even the mail app one day could export a chat backend and we will chat via email?

Indeed, I talked about this with @jancborchardt.

So @DeepDiver1975 I can start writing this?

LEDfan commented 10 years ago

Note that after everything is in, I have to write docs on how to register and create a backend.

DeepDiver1975 commented 10 years ago

So @DeepDiver1975 I can start writing this?

Yes - please. Can we do one quick step before defining the interfaces and quickly write down the requirements/needs for a consumer of the api? We need a common understanding of the use cases before diving into code - THX

BernhardPosselt commented 10 years ago

@DeepDiver1975 so we dump all interfaces of all apps into core? Like when i want people to interface with the news app I create a PR with 3 interfaces?

BernhardPosselt commented 10 years ago

+ a factory class and a way to register the factory?

BernhardPosselt commented 10 years ago

Another solution is to create a table for your app where you list the available backends. Your chat app does a db query to get the backends and requires the backends based on a path like APP_ID/chat/backend.php. Since you can check if its available on the fs you wouldn't even need a setup/uninstall callback for each app (which should be there anyways)

BernhardPosselt commented 10 years ago

It could even be a very generic table like:

app_id | backend_for_app_id

where app_id would be xmpp and backend_for_app_id would be chat for example

DeepDiver1975 commented 10 years ago

Another solution is to create a table for your app where you list the available backends. Your chat app does a db query to get the backends and requires the backends based on a path like APP_ID/chat/backend.php. Since you can check if its available on the fs you wouldn't even need a setup/uninstall callback for each app (which should be there anyways)

Well - there might be a hell of different approaches - each with it's pros and cons. But seriously the public api design has been discussed many times back in Berlin 2013 before the release of OC6.

Let's just accept this approach until we really reach the point where the solution no longer solves a problem. Okay?

karlitschek commented 10 years ago

A completely agree with @DeepDiver1975 This is how the architecture should be

LEDfan commented 10 years ago

Yes - please. Can we do one quick step before defining the interfaces and quickly write down the requirements/needs for a consumer of the api? We need a common understanding of the use cases before diving into code - THX

@DeepDiver1975 I looked over this comment...

First of all, the Chat app is a Chat client* which works in the browser (thus written in JS) which renders the view with the information it gets from the backends. These backends are created as AngularJS factories. Let's say it's an JS object which can be automatically loaded (Via angular's DI) in the browser. (https://github.com/owncloud/chat/blob/master/js/src/app/factories/backends.js#L6-L6) The Chat client should know that these backends exists and should know which conversations it should load at startup. (This changes everytime the Chat client is loaded)

The Chat client get this information when the page is loaded. At the server side the chat app must know which backends exists and what initial conversations it should load. The backend should also get an ID and a displayname. All this information should be exposed as an array. And it should be possible for the backend to provide some extra information to the Chat client.

LEDfan commented 10 years ago

Because the Chat app is a chat client bundled with some backends, it is possible to write another Chat client (with some shared code). Actually this is on the TODO list (https://github.com/owncloud/chat/issues/134).

Becuase it should be possible to provide a Chat backend for apps the IBackend interface and the BackendManager should be in core.

DeepDiver1975 commented 10 years ago

@LEDfan thanks for the detailed technical explanation - but this is not what I was looking for.

I want to see a list of scenarios on how multiple apps can/should interact with each other. From these scenarios we can then derive the interfaces, methods and data structures to be used.

LEDfan commented 10 years ago

@DeepDiver1975 you mean for the Chat app right?

For an app it should be possible to:

This way it can create a chat backend It should also be possible to

This way it can use this information to provide a chat client. No more information is needeed, because the real chatting is handled by the AngularJS factory.

LEDfan commented 10 years ago

Note that the real chatting is handled by the JS code, because for some backends there is already a server running rather then PHP. E.g. for XMPP, an BOSH service is running. This way there isn't any interactio needed between the PHP ownCloud server and the XMPP server.

DeepDiver1975 commented 10 years ago

Sorry - but this is not what I'm looking for. And I doubt that the current approach will be of any use as a public api.

Our php public api needs to be the mediator between ownCloud Apps. As already described above the backend interface needs to provide all necessary integration points which allow somebody to implement a fully capable chat backend - e.g. chat via email.

Further more other app needs to have the capability to use these backends like:

Without this the api is not usable - or at least does not have enough value to become an ownCloud public api.

LEDfan commented 10 years ago

@DeepDiver1975 I understand what you mean. The list you provide, is actually implemented in JS. This because most backends won't be written in PHP nor in ownCloud frameworks. Maybe it's indeed better to move the code to the Chat app.

DeepDiver1975 commented 10 years ago

Maybe it's indeed better to move the code to the Chat app.

seems to be -> closing then