I apologize for sending another message to this thread.

Our primary motivation for limiting access to the Structure API immediately
is straightforward: changing a public API is a major undertaking. By
limiting it now, we will force ourselves to design a universal,
Turing-complete API from the ground up that supports both embedded and
remote deployments.

This approach will enable our users to start with a small embedded database
and scale up to a large cloud cluster without requiring significant
application refactoring.

Best regards,
Andrii Lomakin

On Mon, Nov 24, 2025 at 1:55 PM Andrii Lomakin <[email protected]>
wrote:

> Just to clarify, that is part of our  GraphTraversalDSL
> https://github.com/JetBrains/youtrackdb/blob/develop/core/src/main/java/com/jetbrains/youtrackdb/api/gremlin/YTDBGraphTraversalSourceDSL.java#L49
> .
>
> >I think this idea begs to be explored
>
> We will start experimenting with it then. We have thought about it for a
> long time, so you can base your changes on what we have made.
>
> On Mon, Nov 24, 2025 at 1:51 PM Andrii Lomakin <
> [email protected]> wrote:
>
>> Hi Stephen.
>> Thank you for the feedback. Regarding transactions, after I wrote the
>> letter, I am inclined to think that the approach using GraphTraversal that
>> we currently use is closer to what I want to see in the TinkerPop process
>> API than the steps designed to control TXs.
>>
>> BTW, we use the autoExecute approach a lot :-)
>>
>>   /// Start a new transaction if it is not yet started and executes
>>> passed in code in it.
>>>   ///
>>>   /// If a transaction is already started, executes passed in code in
>>> it. In case of exception,
>>>   /// rolls back the transaction and commits the changes if the
>>> transaction was started by this
>>>   /// method.
>>>   public <X extends Exception> void executeInTx(
>>>       @Nonnull FailableConsumer<YTDBGraphTraversalSource, X> code)
>>> throws X {
>>>     var tx = tx();
>>>     YTDBTransaction.executeInTX(code, (YTDBTransaction) tx);
>>>   }
>>
>>
>>   /// Start a new transaction if it is not yet started and executes
>>> passed in code in it.
>>>   ///
>>>   /// If a transaction is already started, executes passed in code in
>>> it. In case of exception,
>>>   /// rolls back the transaction and commits the changes if the
>>> transaction was started by this
>>>   /// method.
>>>   ///
>>>   /// Unlike {@link #executeInTx(FailableConsumer)} also iterates over
>>> the returned
>>>   /// [YTDBGraphTraversal] triggering its execution.
>>>   public <X extends Exception> void autoExecuteInTx(
>>>       @Nonnull FailableFunction<YTDBGraphTraversalSource,
>>> YTDBGraphTraversal<?, ?>, X> code)
>>>       throws X {
>>>     var tx = tx();
>>>     YTDBTransaction.executeInTX(code, (YTDBTransaction) tx);
>>>   }
>>
>>
>>   /// Start a new transaction if it is not yet started and executes
>>> passed in code in it and then
>>>   /// returns the result of the code execution.
>>>   ///
>>>   /// If a transaction is already started, executes passed in code in
>>> it. In case of exception,
>>>   /// rolls back the transaction and commits the changes if the
>>> transaction was started by this
>>>   /// method.
>>>   public <X extends Exception, R> R computeInTx(
>>>       @Nonnull FailableFunction<YTDBGraphTraversalSource, R, X> code)
>>> throws X {
>>>     var tx = tx();
>>>     return YTDBTransaction.computeInTx(code, (YTDBTransaction) tx);
>>>   }
>>
>>
>> On Mon, Nov 24, 2025 at 1:44 PM Stephen Mallette <[email protected]>
>> wrote:
>>
>>> Generally speaking, I think this idea begs to be explored but I also
>>> think
>>> that it's a change of extraordinary size that will need a lot of thought
>>> and planning to be sure it is done properly. I think initial efforts with
>>> that plan are already underway with 3.8.0 where it introduced the notion
>>> of
>>> StepContract interfaces and "step placeholders" which should allow
>>> providers to more easily provide their own implementations. In this way,
>>> a
>>> provider would be implementing at a Gremlin level rather than at that
>>> Structure API level. So, that's a starting point to allow for any of this
>>> to happen. I don't recall past discussions about what happens to Element
>>> interfaces, but I sense they would end up being read-only as you
>>> described.
>>> I suppose they would stay interfaces and there would be a few concrete
>>> TinkerPop implementations that we'd offer for providers to convert to
>>> when
>>> implementing steps. Remote providers might skip all that together and
>>> just
>>> write directly to GraphSON or GraphBinary.
>>>
>>> I don't know if transactions should explicitly be implemented as a
>>> traditional Step or not. They don't behave like steps in my mind, in
>>> that I
>>> don't see how they chain.  Maybe it's more like a terminal step or a
>>> special step series like io().read()/write(). I think the first work to
>>> be
>>> taken around this big topic is to try to build consensus for what
>>> transactions look like, both as a part of the Gremlin language and the
>>> HTTP
>>> API. I know Ken has been thinking about the Transaction API for 4.x, but
>>> no
>>> formal proposal has been raised yet that I can recall.
>>>
>>> I will add that while I feel the Transaction API is a must-have for 4.x,
>>> I'm not sure that I see removal of the Graph API as a critical item for
>>> that version. If there was consensus on a plan to do so, I think it would
>>> be best for that to fall into a later body of work where perhaps the
>>> deprecation for the Graph API is in 4.x with removal in 5.x.
>>>
>>> On Sat, Nov 22, 2025 at 8:49 AM Andrii Lomakin via dev <
>>> [email protected]> wrote:
>>>
>>> > Dear like-minded colleagues,
>>> >
>>> > Sorry for the stream of ideas, but I wanted to share my thoughts on API
>>> > dual support.
>>> >
>>> > I believe the dual support of two API types—structured and process—is
>>> > counterproductive because it prevents the creation of truly
>>> > platform-independent distributions.
>>> > When an application development team begins to rely on the structured
>>> API,
>>> > they become limited to a minimal number of vendors who support embedded
>>> > deployments.
>>> >
>>> > Furthermore, I agree with Stephen Mallette that it is more
>>> straightforward
>>> > and more idiomatic for a provider to implement a few basic steps that
>>> > operate on database records than to implement the more demanding
>>> interface
>>> > of a Graph instance.
>>> >
>>> > In practice, this suggests the following changes:
>>> >
>>> > 1. Remove the Graph interface as a public API.
>>> > 2. Make the Element, Vertex, and Edge concepts read-only.
>>> > 3. Add steps to control transactions uniformly at the GraphTraversal
>>> level
>>> > to unify management.
>>> >
>>> > Regarding transaction management, the current implementation appears
>>> to be
>>> > an ununified side feature, especially considering the disparate
>>> lifecycles
>>> > between embedded and remote deployments. Introducing steps that
>>> control the
>>> > transaction lifecycle would resolve this issue.
>>> >
>>> > What do you think about these points?
>>> > We will consider implementing those items on our side in the short
>>> term.
>>> >
>>> > Best regards,
>>> > Andrii Lomakin
>>> > YouTrackDB development lead.
>>> >
>>>
>>

Reply via email to