-
Notifications
You must be signed in to change notification settings - Fork 27
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
Defining operations without reflection #751
Comments
Yes, OData has quite a statically defined outlook : ) Some of what you're running into is for the OData metadata, for example To work with the problem you've described, you could implement something a bit like JSON-RPC in OData, where you have a single 'invoke' function, you'd pass the actual method as a string parameter, and an set of arguments as an optional untyped array, and the response is just an open entity type or array. But in this case the OData client would need to understand how to handle this flow. |
First of all: thank you so much for your help! A generic It sounds like Perhaps I'm missing something obvious here, but it seems odd that metadata is so tightly coupled to (static) reflection. Intuitively I'd consider "describing an operation" and "automatically loading a description with reflection" as two separate things. In principle other parts of the code aren't interested in how an operation was described, only what the description ended up being. |
I wrote this code quite a while ago, so my memory might be incorrect!
Based on your example it seems like you have a fixed operation name, but variable arguments. While it's not pretty, if you truly have variable arguments for a specific function name can you do: $f = new Operation\Function_('add');
$f->setCallable(function (?string $arg0, ?string $arg1, ?string $arg2, ?string $arg2): string {
// ...
});
Lodata::add($add); |
Hmmm, another interesting idea, but unfortunately the "set of available operations" is dynamic too in my case. I was working on decoupling the operation system from reflection a couple months ago, until I was rudely interrupted by other things. |
Hiya, I was referring to this: https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ModelVersioning where as long as you're only adding things then that's safe. Of course there's no reason Lodata has to stick to that, if the developer knows what they're doing. So yes I'd be fine with the ability to add operations in ways other than via reflection. |
Oooh interesting, thanks for the reference and your lightning fast response! For completeness: in principle, defining operations 'non-reflectively' doesn't necessarily mean they're 'dynamic'; they could for example be based on a static configuration file. |
Operations use reflection to determine the parameters and return type of their callable.
This works great, but only if your operations can be defined statically, as in "at the time of writing code".
I'm trying to write a "proxy" that exposes some archaic esoteric legacy system as an OData API.
Long story short, it's impossible to statically define this system's operations, they're derived from all sorts of places including user configuration.
Therefore I need a way to dynamically specify operations, for example something along these lines:
I took a shot at decoupling
Operation
from reflection, but unfortunately I ran head-first into a whole lot of trouble, including but certainly not limited to:Operation::returnsCollection
relies on resolving the return type to a class name foris_a
, butOperation::returnType
is of typeType
.Type::factory
should contain a class name, but for some reason this doesn't seem to always be the case.Operation::setReturnType
?Seems to be used for callbacks labeled with
Entity
orEntitySet
, but it's not respected everywhere.Operation
'sreturnsCollection
andisNullable
always use the reflection-basedgetCallableReturnType
.I'm going to keep investigating this, but given my extremely limited knowledge of Lodata's internals I figured I might as well get some input from those in the know :)
What are your thoughts on this kind of feature? Any suggestions on how this could be implemented?
The text was updated successfully, but these errors were encountered: