oasis-open / odata-rapid

Rapid - Specification, tools and libraries to support the development and adoption of simple REST-based APIs.
https://rapid.rocks
Apache License 2.0
17 stars 8 forks source link

Define RSDL directives #43

Closed ralfhandl closed 3 years ago

ralfhandl commented 4 years ago

Directives for

GEricson commented 4 years ago

If we choose graphql like, then objects/fields/... sufficient for structure. Difference between entityset and singleton is the sets would have a list type.

I like the idea of defining CRUD operations explicitly. Filter/Select/... are then just parameters to the corresponding operation declaration.

wtrocki commented 4 years ago

Difference between entityset and singleton is the sets would have a list type.

This work only for types in relations. Not for top level types. I think we have two camps here. @ralfhandl Would like to map singleton/array by @entityset directive

type Test @entityset {

@GEricson I suspect that yourself would like container to exist phisically in RSDL schema

# hardcoded type as convention
type RapidContainer {
  # some conventions here to get etc.
  Tests:[Test]
}

And no one seem to like functional split using existing GraphQL root types:

type query{
 Tests:[Test]
}

type mutation{
}

I will call those 1 2 3 approaches

wtrocki commented 4 years ago

1) Really slick but it might end with so many directives if we bring more capabilities that it might get hard to get nice experience. It is the most sensible approach to start with and explore

2) More OData friendly. Can avoid annotations but it will be harder to explain and learn IMHO. If we looking from perspective of adapting a lots of features from OData it might be better to try it

3) No one seems to be taking this into consideration - it has benefits but it is also verbose like 2 and based on conventions

wtrocki commented 4 years ago

More verbose doesn't mean bad. There is advantage for example instead using directive for filter you can explicitly call out filter properties in the container type in approach 2 or Query in approach 3.

Approach nr 1 seems to be the easiest to implement as 2, 3 might require some validation to check on conventions.

I think that @GEricson has good points but for simplicity I will try nr1 first and then evaluate on top of it to see if nr 2 will give better experience

GEricson commented 4 years ago

@wtrocki : No, I don't think we need entityset directive. I have argued for a long time that EntitySet and Singleton are simply properties of the service declaration. (Or fields in graphql.)

GEricson commented 4 years ago

@wtrocki : The service instance is the container of entities, (not of the modeled resources). We need to create a declaration that defines service instances.

wtrocki commented 4 years ago

I understand what we are suggesting and overal arguments from OData standpoint, but finding hard to see how to apply it to Rapid or RSDL.

type Whatever {
???
}

We need to work with examples. If you do not feel comfortable with RDSL an JSON will do as well

ralfhandl commented 4 years ago

We need to work with examples.

Definitely!

Let’s sketch some examples here, or in a PR with example files, before we decide or start to implement transformations.

I like the schema approach of GraphQL, and I dislike explicit modeling of CUD mutations.

Strong point of OData is that CUD are systematically derived from R structure, allowing automatic round-tripping for read - edit in UI - update.

Maybe use schema { query: ... } for defining entity sets, singletons, and functions, with directives to auto-derive CUD, and use schema { mutation: ... } only for action imports.

Open: how to model “bound actions” like POST /LeaveRequests/42/approval - similar to instance methods in OO.

wtrocki commented 4 years ago

I think we have already in spec on master actions and functions represented in query and mutation. I will be nice to get example for entitySet or singleton in query.

Challenge here is that OData Container is not differentiating between read or writes. Would it be less confusing if we replace Query/Mutation with single RapidContainer type. Another advantage here would be that you could have nice migration from GraphQL that will have queries and mutations and move some types to Rapidcontainer type

wtrocki commented 4 years ago

Actually we still need to differentiate between action and function so ignore me

wtrocki commented 4 years ago

How about having explicit mutation instance

type Query {
  # singleton
  user: User
  ## Set
  users(filter: InputFilter): [User]
}

type Mutation {
  # covers create update delete
  user: User @RapidAction(enabled: [update, delete])
}

Bound and unbound functions are already in spec so not including them here

GEricson commented 4 years ago

I suggest s/@RapidWrite/@RapidAction/ The reason is that action has side-affects, but I don't think necessarily modifies the entity it is bound to.

wtrocki commented 4 years ago

Marking https://github.com/oasis-open/odata-rapid/issues/27 as duplicate

GEricson commented 4 years ago

I agree with @ralfhandl proposal to define entitycontainer through the use of the schema directive.

wtrocki commented 4 years ago

I think this is critical to move entire Rapid forward. The best would be to edit RSDL.md file and add those topics - each of us can create different PRs based on our understanding and we can discuss and pick something that will work - it will be easier.to have 1 2 3 approaches as separate PRs and pick one. It will not mean we will need to stick with it but having something is better than nothing

wtrocki commented 4 years ago

FYI @oasis-open/odata-rapid-write

ralfhandl commented 3 years ago

Related to abandoned approach to base RSDL on GraphQL schema