Service based app imlpementation to solve inter-app dependencies

expert
architecture

#1

One common issue is that for some apps there is one app implementing some APIs and another one using it. This creates inter-app dependencies which so far was frowned upon.

For this reason, some app's code and interfaces has been moved into core to make sure other apps can use it.

Let's take the existing activity feature as an example:
- core contains an ActivityManager (Activity\IManager) that apps can use to publish activities (Backend)
- the owncloud/activity app connects to it to be able to display activities (Frontend)
- other apps (ex: files, calendar, etc) would connect to the ActivityManager to publish activities like "file was renamed", "calendar event was created", etc (publishers/clients)

What if in the future someone would implement an app that implements another service that doesn't exist in core ? That app would need to submit a PR to core with the necessary code. This is a no go for complex app development.

To solve this, here is an idea: let apps be either a provider or a consumer of services.
A service is simply a class with a namespace and an interface, defined in info.xml.

If we model the activity feature after this there would be three different apps:
- activity-service: an app that only provides the backend for publishing activities. Its info.xml would declare that it provides a service called "IActivityManager"
- activity-frontend: an app that displays a list of activities in a full page. Its info.xml would declare that it requires a service called "IActivityManager". The requirement here would be a hard-requirement, so the app cannot be enabled if there is no other app providing "IActvitiyManager"
- files: the files app would declare in its info.xml that it optionally requires a service called "IActivityManager". Optional means that if no app provides this service, the app can still be enabled but will skip publishing activities
- calendar: same as files

Now with this model, maybe someone writes another app that implements "IActivityManager" better. That app could also declare that it provides this service. Now if two apps are enabled providing the same service, either it should be denied or the clients need to be able to select one of them. This case might be rare though.

Also, nothing speaks against having one app implement both the service and consume it at the same time. But having the service "public" as part of info.xml makes it possible for other apps to use it too.

If we go that route, a lot of core code could be moved to apps eventually and have core be lighter.


Moving app development to the next level, better APIs, cleaner code
#2

Vince, this is perfectly suiting in the idea of micro services which will ease and clarify development and scalability customizations in my opinion. Awesome job of defining a problem!


#3

Yes!, leave the core light, simple and stable!


#4

Now we could also group a set of these services into "app permissions", a bit like Android does.

If an app requires the service "IUserSession" then it requires the permission "user info permission"
For accessing the filesystem (Node API), it requires the permission "access to user's storage".
For accessing the root filesystem (Node API), it requires the permission "access all user's storages".
For accessing all user info (provisioning API), requires permission "access all users info".

This could also be read-only / read-write.

Maybe this could even tie in with future oauth scopes. If a service declares its methods with oauth scopes, some methods could be blocked. Or simply we could provide the services as smaller subsets of interfaces with at least a read-only one and read-write one. This way we could assign services with OAuth scopes.

And whenever a permission is not granted for an app despite it requiring the service, the injector would simply inject null there. Note that in such case the service might still exist and be available from a specific app, but is specifically blocked by the admin or by the current oauth scope.

It seems we'd have some kind of orchestrator / hub that does the service wiring based on providers and permissions.