Hi all Thanks for all the updates. The KIP looks vote-ready to me. Just one very small nit / side suggestion: I think MultipleKeys works, but it feels a bit imprecise since the interface exposes exactly two keys (mapped + stream). Something like ValueJoinerWithMappedAndStreamKey or ValueJoinerWithJoinKeys might be a bit more literal.
-Alieh On Tue, Jun 23, 2026 at 12:15 AM Lucy Liu via dev <[email protected]> wrote: > Hi all, > > Thanks for the feedback. I've updated the KIP to reflect the overload-based > approach we discussed: > > - A new functional interface `ValueJoinerWithMultipleKeys<K1, K2, V1, V2, > VR>` that exposes both the mapped join key and the stream record key (using > the name Matthias suggested, to avoid the easy-to-miss collision with > `ValueJoinerWithKey`). > - Four new overloads of `KStream#join` / `leftJoin` (the GlobalKTable > variants) taking the new joiner. > - The four existing `ValueJoinerWithKey`-based overloads are deprecated, > with Javadoc that explicitly calls out that `readOnlyKey` there is the > stream key, not the join key, and points users at the new method. > - The original `joinByMappedKey` / `leftJoinByMappedKey` proposal is now > listed under Rejected Alternatives. > > Updated KIP URL: > > https://urldefense.com/v3/__https://cwiki.apache.org/confluence/display/KAFKA/KIP-1340*3A*Expose*Both*Mapped*Key*and*Stream*Key*in*Streams-GlobalKTable*Joins__;JSsrKysrKysrKys!!Ayb5sqE7!tC3gNrg95XuzvIZ9GVPE6UN-JPEB8M3LuJX7cJ8fKS9OH-bNgUAR6EojEGr_SjDeZhlqzXlC6wUAa4kPxpU$ > > Happy to hear further feedback. > > Best regards, > Lucy Liu > > On Mon, Jun 22, 2026 at 1:13 PM Matthias J. Sax <[email protected]> wrote: > > > The only name I could come up with is `ValueJoinerWithMultipleKeys` ? > > > > > > -Matthias > > > > On 6/12/26 2:47 AM, Alieh Saeedi via dev wrote: > > > Thanks Lucy and Matthias. > > > > > > > > > > > > > > > > > > I also lean toward the second approach (the ValueJoinerWithKeys > > overload). > > > Although the initial approach is an easier fix, the future for each > > > approach would be: > > > - Under the second approach: one join family — join/leftJoin — with > > > different joiner flavors. It's internally consistent and learnable from > > > existing knowledge. > > > > > > - Under the first approach: join for some variants and > joinByMappedKey > > > for others — a method name that appears nowhere else in the API, > > justified > > > by an internal detail/nuance (mapped key != record key) > > > > > > > > > Just one thing I'd want to raise: The naming: ValueJoinerWithKeys > > (plural) > > > is one character different from the existing "ValueJoinerWithKey" > > > (singular). Since both live in the same package and appear together in > > > autocomplete, this naming similarity is an easy long-term footgun (also > > > confusing). Could we consider a less collision-prone name? I don't > have a > > > great one yet, but I'd raise it now than after it's public. > > > > > > > > > Thanks > > > - Alieh > > > > > > > > > On Fri, Jun 12, 2026 at 3:06 AM Matthias J. Sax <[email protected]> > > wrote: > > > > > >> Thanks for digging into the details. > > >> > > >> What you found matches my understanding. Overall, it's a tricky > > >> tradeoff. Personally, I think it's better to keep the more prominent > > >> API, ie, KStream#join() clean, so the alternative to add > > >> `ValueJoinerWithKeys` (plural) might be the better tradeoff. > > >> > > >> Would be good to also hear from others about it. > > >> > > >> > > >> -Matthias > > >> > > >> > > >> On 6/4/26 12:44 PM, Lucy Liu via dev wrote: > > >>> Hi Matthias, thanks for the feedback! > > >>> > > >>> MJS1: Yes, compile-time, not runtime. I reworded that. > > >>> > > >>> MJS2, MJS3, MJS4: > > >>> I agree that introducing the new methods will lead to name asymmetry. > > If > > >> we > > >>> add a new join/leftJoin overload taking a new functional interface > > rather > > >>> than introducing new methods, all stream-globalTable joins could keep > > the > > >>> same join/leftJoin naming. So I explored the last rejected > alternative > > >>> further: a new ValueJoinerWithKeys interface `ValueJoinerWithKeys<K1, > > K2, > > >>> V1, V2, VR>` with `apply(readOnlyKey, streamKey, value1, value2)` > > >> exposing > > >>> both keys, and overloaded the existing join/leftJoin methods to > accept > > >> it. > > >>> The four ValueJoinerWithKey overloads get @Deprecated as in the > > original > > >>> plan, but the migration target is now the new overload rather than a > > >>> renamed method. The ValueJoiner overloads stay untouched. > > >>> For example, the new `join` method would be: > > >>> > > >>>> <GlobalKey, GlobalValue, VOut> KStream<K, VOut> join(final > > >>>> GlobalKTable<GlobalKey, GlobalValue> globalTable, > > >>>> final > > >>>> KeyValueMapper<? super K, ? super V, ? extends GlobalKey> > keySelector, > > >>>> final > > >>>> ValueJoinerWithKeys<? super GlobalKey, ? super K, ? super V, ? super > > >>>> GlobalValue, ? extends VOut> joiner); > > >>> > > >>> > > >>> I think this could be a better solution because the overload works > > >> cleanly, > > >>> and the joiner allowing both keys offers greater flexibility. > > >>> This is some draft code changes this approach would introduce: > > >>> > > >> > > > https://urldefense.com/v3/__https://github.com/apache/kafka/pull/22477__;!!Ayb5sqE7!t-Pgojx5hrlsNZCev0a6uksclbJfRMZotq56k4WSPVrACGz_vECOVEhjiAQqr7bMkJEQqbWHHCtUCY-1$ > > >>> > > >>> Happy to learn what others think about this approach. If this > approach > > is > > >>> indeed better, I will update the KIP. > > >>> > > >>> Best regards, > > >>> Lucy Liu > > >>> > > >>> > > >>> > > >>> On Wed, Jun 3, 2026 at 4:43 PM Matthias J. Sax <[email protected]> > > wrote: > > >>> > > >>>> Thanks for the KIP Lucy. > > >>>> > > >>>> Overall, it seems to be a non-controversial proposal, to solve the > > issue > > >>>> with new overloads. > > >>>> > > >>>> > > >>>> > > >>>> MJS1: The KIP says: > > >>>> > > >>>>> The discrepancy is not surfaced at runtime > > >>>> > > >>>> What this paragraph describe is a compile time type check, right? > Not > > a > > >>>> runtime check? > > >>>> > > >>>> > > >>>> > > >>>> MJS2: It seems you propose to replace only the 4 methods which take > > >>>> `ValueJoinerWithKey` argument. While this is the smallest change we > > >>>> could make, I am wondering if it introduced some name > inconsistencies? > > >>>> So even if technically not necessary, I am wondering if we would get > > >>>> better UX, if we would also deprecate the 4 method taking > > `ValueJoiner`? > > >>>> This way, all method which are doing the same thing, ie > > >>>> stream-globalTable join have the same name. > > >>>> > > >>>> > > >>>> > > >>>> MJS3: About naming the new methods. I guess both `joinOnMappedKey` > and > > >>>> `joinByMappedKey` would work. But I am wondering if > > >>>> `foreignKeyJoin()`would be good names, too? Or maybe > > >>>> `globalKTableJoin()`? Just putting forward some alternatives to > spark > > >>>> some thoughts. Naming is always hard. Curious to hear what others > > think. > > >>>> > > >>>> > > >>>> > > >>>> MJS4: About the last rejected alternative. If my assessment is > right, > > it > > >>>> would have the advantage that we could add new overloads called > > >>>> `join()`, and thus we would get better method naming overall, and my > > >>>> point MJS2 from above would become void? I does have the > disadvantage > > >>>> that we need a new interface, but given the naming question, I am > > >>>> wondering if it would provide an overall better tradeoff? -- Again, > > >>>> curious to hear what others think. > > >>>> > > >>>> > > >>>> -Matthias > > >>>> > > >>>> > > >>>> > > >>>> On 5/27/26 10:17 PM, Lucy Liu via dev wrote: > > >>>>> Hi Bill, > > >>>>> > > >>>>> Thanks for the suggestions! I have made some changes accordingly. > > >>>>> BB1: I changed the 4 added methods to use `by` instead of `on`. > > >>>>> BB2: For each deprecated method, an additional warning comment will > > be > > >>>>> added, stressing that the `readOnlyKey` is the stream key and might > > not > > >>>> be > > >>>>> behaving as intended. > > >>>>> > > >>>>> Best, > > >>>>> Lucy > > >>>>> > > >>>>> On Wed, May 27, 2026 at 4:07 PM Bill Bejeck <[email protected]> > > >> wrote: > > >>>>> > > >>>>>> Hi Lucy, > > >>>>>> > > >>>>>> Thanks for the KIP! This is a very much needed update to Kafka > > >> Streams. > > >>>>>> Overall the KIP looks good. > > >>>>>> > > >>>>>> BB1. I have one nit comment with regards to the name. What would > > you > > >>>> think > > >>>>>> about `joinByMappedKey / leftJoinByMappedKey` instead? > > >>>>>> BB2. Since the error condition will continue to exist until we > > remove > > >>>> the > > >>>>>> deprecated methods, maybe we could add one line to the Javadoc > > >>>> explicitly > > >>>>>> stating that readOnlyKey is currently the stream key, not the > mapped > > >>>> join > > >>>>>> key. > > >>>>>> > > >>>>>> Thanks, > > >>>>>> Bill > > >>>>>> > > >>>>>> On Tue, May 26, 2026 at 1:19 PM Lucy Liu via dev < > > >> [email protected]> > > >>>>>> wrote: > > >>>>>> > > >>>>>>> Hi everyone, > > >>>>>>> > > >>>>>>> Gentle ping on this thread. Looking forward to feedback on the > KIP! > > >>>>>>> > > >>>>>>> Best, > > >>>>>>> Lucy Liu > > >>>>>>> > > >>>>>>> On Fri, May 15, 2026 at 4:19 PM Lucy Liu <[email protected]> > > >> wrote: > > >>>>>>> > > >>>>>>>> Hello everyone, > > >>>>>>>> > > >>>>>>>> I would like to start a discussion on KIP-1340 Pass Join Key to > > >>>>>>>> `ValueJoinerWithKey` in Streams-GlobalKTable Joins > > >>>>>>>> < > > >>>>>>>> > > >>>>>>> > > >>>>>> > > >>>> > > >> > > > https://urldefense.com/v3/__https://cwiki.apache.org/confluence/display/KAFKA/KIP-1340*3A*Pass*Join*Key*to**A60ValueJoinerWithKey*60*in*Streams-GlobalKTable*Joins__;JSsrKysrJSUrKys!!Ayb5sqE7!sMsc7OEJtzyBJn3kfDmAjAi8gklV-8hDbb2Oiwk_NV0RC8giJPWimU7sX4jc4Niu_29yjxAv1souD4H5kUY$ > > >>>>>>>>> > > >>>>>>>> > > >>>>>>>> This proposal aims to introduce joinOnMappedKey and > > >>>>>> leftJoinOnMappedKey, > > >>>>>>>> new KStream methods that pass the mapped join key (the result of > > the > > >>>>>>>> user-supplied KeyValueMapper) into ValueJoinerWithKey for > > >>>>>>>> stream-globalTable joins. The existing join/leftJoin overloads > > pass > > >>>> the > > >>>>>>>> stream record's key into the joiner instead, contradicting > > KIP-149's > > >>>>>>>> contract that readOnlyKey is the join key and silently producing > > >> wrong > > >>>>>>>> values if a joiner intends to read the real join key. The > existing > > >>>>>>>> overloads will be deprecated and removed in a future major > > release. > > >>>>>>>> > > >>>>>>>> Best regards, > > >>>>>>>> Lucy Liu > > >>>>>>>> > > >>>>>>> > > >>>>>> > > >>>>> > > >>>> > > >>>> > > >>> > > >> > > >> > > > > > > > >
