[dev] RPC and REST

Ralf Lang lang at b1-systems.de
Tue Oct 17 20:07:47 UTC 2017


Hallo,

lately I have been examining the REST and RPC topics discussed in January.

Bad news is it doesn't quite fit and I am not sure if it's a good idea 
to cram it into the RPC framework. It looks more and more like Rest 
should sit on top of the inter-app API, separate from RPC.


For example, let's have

PUT /rpc/rest/admin/user/henry

to create a new user "henry" (identity details and auth credentials 
random or undefined)

/rpc/ (or /rpc.php) is our universal endpoint for all rpc-ish stuff.
/rpc/rest/ to discern rest from other users of the rpc endpoint (dav, 
phpgw, json-rpc, whatever)

The existing RPC backends all have a clear and easy separation of api, 
command/method and parameters which can be mapped to the internal 
inter-app api and are happy to just return any scalar or array structure 
as the single result.

REST on the other hand may have parameters as part of the URL path, as 
argument (in GET), as part of the request body (in POST) and the result 
should yield a meaningful status code



To make REST automatically fit into the existing RPC framework, it would 
require to limit it to a fixed /api/resource/$param/$param.. format with 
resource and method defining the horde api method - and then we would 
need to create method names like admin.putUser("henry")

We can make this more straight forward if every resource is its own api

user.put("henry") -> PUT /rpc/rest/user/henry

Of course, allowing for named parameters would make this more versatile 
but registry->call does not have named parameters.

Still, methods like put and get instead of create/list don't blend well 
with the rest of rpc methods.

Bottom line is:

It might make sense to have rpc.php as the common endpoint for 
everything (dav, json-rpc, rest).

It might also make sense to have both RPC and REST wrap the bare 
inter-app API into something providing more context on allowed, required 
and optional parameters (and formats, auth / no auth, limiting...) but I 
do not see any way to make REST feel right as yet another Rpc driver 
interfacing the same set of remote execution methods. At least not 
without yet another wrapping layer to be coded for each exposed resource.


Apart from that, Horde_Rpc has some limitations I looked into:

It's implicitly assuming to have a horde registry global variable around 
to provide Api Methods (see Horde_Rpc_Xmlrpc) line 34

It's not allowing any parameter to override this

The specific class factory is part of the base class

No way to ensure methods for Horde inter-app communication and external 
Apis can be separated

Authentication and Authorization is not really separated from the modules

For example, some reading calls may make sense to expose to the 
unauthenticated public, others should only be available to authenticated 
users, to admins or to users with a specific horde permission.

Inter-App calls should be able to yield PHP Objects, but the Rpc modules 
are currently not fit to auto-convert them into arrays and scalars for 
serialization to external interfaces

If an app has two apis, currently all methods show up for both apis. 
Separate per api classes instead of one monolithic Api.php per app may help.

I'd like to go for separate per action classes but this creates problems 
with implementing listMethods, unless I explicitly declare them in 
registry.php or in said per api class.

Separate the api provider (list of valid methods) from the Rpc backends 
(ship a dummy provider with Horde_Rpc, ship the horde-specific provider 
with Horde_Core)

Separate the authentication provider from the Rpc backends (for now, 
AuthHorde, AuthSeparate and Null should be sufficient)




-- 
Ralf Lang
Linux Consultant / Developer
Tel.: +49-170-6381563
Mail: lang at b1-systems.de
B1 Systems GmbH
Osterfeldstraße 7 / 85088 Vohburg / http://www.b1-systems.de
GF: Ralph Dehner / Unternehmenssitz: Vohburg / AG: Ingolstadt,HRB 3537


More information about the dev mailing list