Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building SQL-Free Apps with MySQL REST Service,...

Avatar for lefred lefred
October 03, 2025

Building SQL-Free Apps with MySQL REST Service, Helidon, and OCI GenAI

This session, delivered during a SouJava Meetup, presents a practical approach to simplifying app development.

I go through the process of creating a Java application as a newbie with Helidon and provide value to the data stored in MySQL using GenAI.

All data is accessed without a single line of SQL.

Avatar for lefred

lefred

October 03, 2025
Tweet

More Decks by lefred

Other Decks in Technology

Transcript

  1. Frédéric Descamps Community Manager Oracle MySQL SouJava - October 2025

    Building SQL-Free Apps with MySQL REST Service, Helidon, and OCI GenAI A Practical Approach to Simplifying App Development
  2. • @lefred • @lefredbe.bsky.social • @[email protected] • @lefred14:matrix.org • MySQL

    Evangelist • using MySQL since version 3.20 • devops believer • living in • h�ps://lefred.be Frédéric Descamps Copyright @ 2025 Oracle and/or its affiliates. 3
  3. Motivation As SQL is not the most developer-friendly language, the

    �rst motivation is to simplify application development by removing the need to write SQL queries directly in the application code. Copyright @ 2025 Oracle and/or its affiliates. 5
  4. Motivation As SQL is not the most developer-friendly language, the

    �rst motivation is to simplify application development by removing the need to write SQL queries directly in the application code. For some years now, the delevelopment has been spli�ed between frontend and backend, and the backend is often a REST API. And this is exactly what MySQL REST Service (MRS) provides: a REST API to access the database. Copyright @ 2025 Oracle and/or its affiliates. 5
  5. Motivation As SQL is not the most developer-friendly language, the

    �rst motivation is to simplify application development by removing the need to write SQL queries directly in the application code. For some years now, the delevelopment has been spli�ed between frontend and backend, and the backend is often a REST API. And this is exactly what MySQL REST Service (MRS) provides: a REST API to access the database. The second motivation is to build a modern application, using the latest technologies, such as microservices, real-time events, and AI. Copyright @ 2025 Oracle and/or its affiliates. 5
  6. Use Case For our application, we will use the Sakila

    sample database, which is a common database for learning purposes. It contains information about a video rental store, including �lms, actors, customers, and rentals. h�ps://dev.mysql.com/doc/sakila/en/ And for the Java framework, we will use Helidon, which is a lightweight Java microservices framework from Oracle. It is designed for building cloud-native applications and has good integration with Oracle Cloud Infrastructure (OCI) services, including OCI GenAI in its latest development release. Copyright @ 2025 Oracle and/or its affiliates. 6
  7. Technologies Used - Recap • MySQL REST Service (MRS) →

    SQL-free database access • Helidon Framework → Lightweight Java microservices framework • OCI GenAI + LangChain4j → AI integration for smart data insights • Server-Sent Events (SSE) → Real-time updates to the browser Copyright @ 2025 Oracle and/or its affiliates. 7
  8. Why Helidon? • Open-source framework from Oracle • Built for

    cloud-native applications • Integrated support for OCI services and GenAI (Langchain4j support in 4.3+) • Quick developer feedback (community responsiveness) • They have a cool team! Copyright @ 2025 Oracle and/or its affiliates. 8
  9. Architecture Overview Application �ow: • Users authenticate → App •

    App authenticates → MRS • MRS → REST endpoints → Database • SSE → push changes in real time • OCI GenAI → enrich data with AI insights Copyright @ 2025 Oracle and/or its affiliates. 9
  10. What is MySQL REST Service? The MySQL REST Service is

    a next-generation JSON Document Store solution, enabling fast and secure HTTPS access for data stored in MySQL, HeatWave, InnoDB ClusterSet and InnoDB ReplicaSet. Being a fully integrated MySQL solution, it focuses on ease-of-use, support of standards and high performance. Copyright @ 2025 Oracle and/or its affiliates. 11
  11. • RESTful Web Services • REST SQL Extension • Powerful

    Data Mapping • Client SDK Generation What is MySQL REST Service? (2) The MySQL REST Service consists of four major building blocks, delivering an integrated solution for JSON Document-based application development. Copyright @ 2025 Oracle and/or its affiliates. 12
  12. What is MySQL REST Service? (3) 1. RESTful Web Services

    • Auto REST for tables, views and routines • {JSON} responses with paged results • Developer support (GUI, CLI, API) • Support for popular OAuth2 services MySQL REST Service Fast, Secure HTTPS access for MySQL Data & Apps 2. REST SQL Extension sql> CONFIGURE REST METADATA; sql> CREATE REST SERVICE /myService; sql> CREATE REST SCHEMA /sakila ON SERVICE /myService FROM `sakila`; • Fully manageable through REST SQL extension • FullGUI support for increased ease-of-use 3. Powerful Data Mapping • Nested TABLEs to REST endpoints mapping • Visual Data Mapping Editor to build complex JSON structures with ease • SQL & SDK Preview 4. ClientSDK Generation • Tailored SDK for all RESTful Endpoints • Fully-typed SDK to prevent errors • Popular, Prisma-like API,liveprototyping Copyright @ 2025 Oracle and/or its affiliates. 13
  13. MySQL App Development Common DB Development Architectures vs. MySQLREST Service

    Development Classic Client/ServerJav a/C#/... Apps MySQL Protocol/SQL Application Servers + ORM Web Apps MySQL REST Service - Serverless Architecture MicroServi ces API Gateways Classic PHP/Java/... Web Apps MySQL Protocol Micro-Service Architecture MySQL REST Service - Mobile Apps/PWAs/Edge Application Server+ ORM+ W eb Servers MySQL Protocol/SQL HTTPS Web Servers+ PHP ORM HTTPS/CRUD HTTPS MySQL Protocol Functions API Gateways HTTPS/ CRUD Limited to Local Networks Still used, but limiting for Mobile/PWAs Good, but complex solution Good, but hard to integrate Pure, simplified solution for PWAs/Mobile HTTPS/CRUD fitting well into modern architecture Classic App Development REST Service Copyright @ 2025 Oracle and/or its affiliates. 14
  14. MySQL REST Service - how to access? MySQL REST Service

    provides a RESTful API to access the database. The service that exposes the REST API is called MRS and is available: • through MySQL Router (default) • on MySQL HeatWave on OCI and AWS • directly on MySQL Server with the MySQL REST Service Component (currently as LAB release) Copyright @ 2025 Oracle and/or its affiliates. 15
  15. Helidon 4.3.0-M2 • Latest development release (September 2025) • I

    used the SE version, which is lightweight and �exible. • It supports OCI GenAI integration via LangChain4j. < <parent parent> > < <groupId groupId> >io.helidon.applications io.helidon.applications</ </groupId groupId> > < <artifactId artifactId> >helidon-se helidon-se</ </artifactId artifactId> > < <version version> >4.3.0-M2 4.3.0-M2</ </version version> > < <relativePath relativePath/> /> </ </parent parent> > Copyright @ 2025 Oracle and/or its affiliates. pom.xml 28
  16. Helidon - Usage • Create a Main class with a

    main method to start the server. public public class class Main Main { { public public static static void void main main( (String String[ [] ] args args) ) { { . .. .. . WebServer WebServer server server = = Server Server. .builder builder( () ) . .config config( (config config. .get get( ("server" "server") )) ) . .routing routing( (( (r r) ) -> -> { { r r. .get get( ("/" "/", , ( (req req, , res res) ) -> -> res res. .send send( ("Helidon 4.3 + MySQL REST Service + AI" "Helidon 4.3 + MySQL REST Service + AI") )) ); ; . .. .. . } }) ) . .build build( () ) . .start start( () ); ; } } } } Copyright @ 2025 Oracle and/or its affiliates. Main.java 29
  17. Copyright @ 2025 Oracle and/or its affiliates. Please note that

    this is my first Java and Helidon application, so I might not be using all the best practices. 30
  18. Helidon - Routing I've added routes to handle HTTP requests

    while writing the code. • get("/", ...) → Home page • Auth routes → Login, Logout, hash creation • Ui routes → The main web pages for the application. • SseRoutes → Real-time updates • AiRoutes → AI-powered features Copyright @ 2025 Oracle and/or its affiliates. 31
  19. Helidon - Routing (2) public public class class Main Main

    { { public public static static void void main main( (String String[ [] ] args args) ) { { . .. .. . WebServer WebServer server server = = Server Server. .builder builder( () ) . .config config( (config config. .get get( ("server" "server") )) ) . .routing routing( (( (r r) ) -> -> { { r r. .get get( ("/" "/", , ( (req req, , res res) ) -> -> res res. .send send( ("Helidon 4.3 + MySQL REST Service + AI" "Helidon 4.3 + MySQL REST Service + AI") )) ); ; Auth Auth. .registerRoutes registerRoutes( (r r, , mrs mrs) ); ; Ui Ui. .registerRoutes registerRoutes( (r r) ); ; ApiRoutes ApiRoutes. .registerRoutes registerRoutes( (r r, , mrs mrs) ); ; SseRoutes SseRoutes. .registerRoutes registerRoutes( (r r) ); ; AiRoutes AiRoutes. .registerRoutes registerRoutes( (r r, , mrs mrs, , chatService chatService) ) } }) ) . .build build( () ). .start start( () ); ; } } } } Copyright @ 2025 Oracle and/or its affiliates. Main.java 32
  20. Classes This is how the source code is structured: ├──

    ai ├── ai │ ├── DiscoveryChatService.java │ ├── DiscoveryChatService.java │ └── package-info.java │ └── package-info.java ├── AiRoutes.java ├── AiRoutes.java ├── ApiRoutes.java ├── ApiRoutes.java ├── Auth.java ├── Auth.java ├── LoginPage.java ├── LoginPage.java ├── Main.java ├── Main.java ├── MrsClient.java ├── MrsClient.java ├── package-info.java ├── package-info.java ├── SseHub.java ├── SseHub.java ├── SseRoutes.java ├── SseRoutes.java └── Ui.java └── Ui.java Copyright @ 2025 Oracle and/or its affiliates. 33
  21. Authentication Two layers: • App authenticates to MRS • Users

    authenticate to the application (bcrypt hashed passwords) ◦ Flexible migration path for existing applications Copyright @ 2025 Oracle and/or its affiliates. 34
  22. Authentication (2) - MRS MySQL REST Service supports multiple authentication

    methods: Copyright @ 2025 Oracle and/or its affiliates. 35
  23. Authentication (3) Currently, none of the methods are supported by

    Helidon out of the box, so I implemented the easiest one which is the MySQL one: Copyright @ 2025 Oracle and/or its affiliates. 36
  24. Authentication (4) This authentication is for the application to use

    MRS. This is not the default way to use MRS, usually each user has its own access to MRS, but this also means that it's not easy to migrate an existing application to MRS. The native MRS authentication method uses SCRAM. This is hard to implement easily in Helidon. A feature request has been created to support SCRAM natively in Helidon: h�ps://github.com/helidon-io/helidon/issues/10628 Copyright @ 2025 Oracle and/or its affiliates. 37
  25. Authentication (4) This authentication is for the application to use

    MRS. This is not the default way to use MRS, usually each user has its own access to MRS, but this also means that it's not easy to migrate an existing application to MRS. The native MRS authentication method uses SCRAM. This is hard to implement easily in Helidon. A feature request has been created to support SCRAM natively in Helidon: h�ps://github.com/helidon-io/helidon/issues/10628 The authentication to MySQL REST Service is done in the MrsClient class. Copyright @ 2025 Oracle and/or its affiliates. 37
  26. Authentication (5) - Users For our users to authenticate to

    the application, I created a simple authentication system using bcrypt hashed passwords that are stored in the database as the good old days. CREATE CREATE TABLE TABLE ` `users users` ` ( ( ` `user_id user_id` ` int int unsigned unsigned NOT NOT NULL NULL AUTO_INCREMENT AUTO_INCREMENT, , ` `firstname firstname` ` varchar varchar( (30 30) ) DEFAULT DEFAULT NULL NULL, , ` `lastname lastname` ` varchar varchar( (30 30) ) DEFAULT DEFAULT NULL NULL, , ` `username username` ` varchar varchar( (30 30) ) DEFAULT DEFAULT NULL NULL, , ` `email email` ` varchar varchar( (50 50) ) DEFAULT DEFAULT NULL NULL, , ` `password_hash password_hash` ` varchar varchar( (60 60) ) DEFAULT DEFAULT NULL NULL, , ` `updated_at updated_at` ` timestamp timestamp NOT NOT NULL NULL DEFAULT DEFAULT CURRENT_TIMESTAMP CURRENT_TIMESTAMP ON ON UPDATE UPDATE CURRENT_TIMESTAMP CURRENT_TIMESTAMP, , PRIMARY PRIMARY KEY KEY ( (` `user_id user_id` `) ) ) ) ENGINE ENGINE= =InnoDB InnoDB DEFAULT DEFAULT CHARSET CHARSET= =utf8mb4 utf8mb4 COLLATE COLLATE= =utf8mb4_0900_ai_ci utf8mb4_0900_ai_ci Copyright @ 2025 Oracle and/or its affiliates. 38
  27. Authentication (6) - Users sql sql> > select select username

    username, , password_hash password_hash from from users users; ; + +----------+--------------------------------------------------------------+ ----------+--------------------------------------------------------------+ | | username username | | password_hash password_hash | | + +----------+--------------------------------------------------------------+ ----------+--------------------------------------------------------------+ | | fred fred | | $ $2 2a$ a$12 12$EW $EW. .Dli9DEMig0Nby Dli9DEMig0Nby/ /zjhSeJVdi4DVsL12Rj zjhSeJVdi4DVsL12Rj/ /qgz qgz. .em69rUyGxXyz em69rUyGxXyz. . | | + +----------+--------------------------------------------------------------+ ----------+--------------------------------------------------------------+ OK OK, , 1 1 record retrieved record retrieved in in 1.16 1.16ms ms Copyright @ 2025 Oracle and/or its affiliates. 39
  28. Authentication (6) - Users sql sql> > select select username

    username, , password_hash password_hash from from users users; ; + +----------+--------------------------------------------------------------+ ----------+--------------------------------------------------------------+ | | username username | | password_hash password_hash | | + +----------+--------------------------------------------------------------+ ----------+--------------------------------------------------------------+ | | fred fred | | $ $2 2a$ a$12 12$EW $EW. .Dli9DEMig0Nby Dli9DEMig0Nby/ /zjhSeJVdi4DVsL12Rj zjhSeJVdi4DVsL12Rj/ /qgz qgz. .em69rUyGxXyz em69rUyGxXyz. . | | + +----------+--------------------------------------------------------------+ ----------+--------------------------------------------------------------+ OK OK, , 1 1 record retrieved record retrieved in in 1.16 1.16ms ms We also use the MySQL REST API to search for the users and compare the password hashes: String String qJson qJson = = "{\"username\":{\"$eq\":\"" "{\"username\":{\"$eq\":\"" + + escapeJson escapeJson( (username username) ) + + "\"}}" "\"}}"; ; String String encoded encoded = = "q=" "q=" + + URLEncoder URLEncoder. .encode encode( (qJson qJson, , StandardCharsets StandardCharsets. .UTF_8 UTF_8) ) + + "&limit=1" "&limit=1"; ; String String json json = = mrs mrs. .get get( ("/sakila/users/" "/sakila/users/", , encoded encoded) ); ; Copyright @ 2025 Oracle and/or its affiliates. 39
  29. Authentication (7) - class The authentication logic is in the

    Auth class, which provides routes for login and logout: • r.get("/login", (req, res) • r.post("/auth/login", (req2, res2) • r.get("/auth/logout", (req2, res2) • r.get("/debug/hash", (req, res) Copyright @ 2025 Oracle and/or its affiliates. 40
  30. Authentication (7) - class The authentication logic is in the

    Auth class, which provides routes for login and logout: • r.get("/login", (req, res) • r.post("/auth/login", (req2, res2) • r.get("/auth/logout", (req2, res2) • r.get("/debug/hash", (req, res) $ $ curl curl 'http://127.0.0.1:8080/_debug/hash?pwd=Brazil' 'http://127.0.0.1:8080/_debug/hash?pwd=Brazil' $2a $2a$12 $12$sm6mKjK $sm6mKjK.fN9BMTUms0KyEeitrLtc0EUW9o7hJwm7bePEVBF5m8Yba .fN9BMTUms0KyEeitrLtc0EUW9o7hJwm7bePEVBF5m8Yba Copyright @ 2025 Oracle and/or its affiliates. 40
  31. Real-Time Updates If we want to show real-time updates in

    the browser, we need a way to push updates from the server (also the database) to the client. Problem: Polling vs WebSockets → too complex/ine�cient Solution: Server-Sent Events (SSE) Simplicity: minimal JavaScript, fully integrated with Helidon Copyright @ 2025 Oracle and/or its affiliates. 41
  32. Server-Sent Events (SSE) SSE is a standard for pushing updates

    from the server to the client over HTTP. It is simpler than WebSockets and works well for many use cases and is supported natively in Helidon. We use two classes: • SseHub → manages SSE connections and broadcasts messages • SseRoutes → de�nes the SSE endpoint and handles client connections Copyright @ 2025 Oracle and/or its affiliates. 42
  33. Server-Sent Events (SSE) - class final final class class SseHub

    SseHub { { private private static static final final SseHub SseHub INSTANCE INSTANCE = = new new SseHub SseHub( () ); ; static static SseHub SseHub get get( () ) { { return return INSTANCE INSTANCE; ; } } private private final final Set Set< <SseSink SseSink> > sinks sinks = = ConcurrentHashMap ConcurrentHashMap. .newKeySet newKeySet( () ); ; void void add add( (SseSink SseSink sink sink) ) { { sinks sinks. .add add( (sink sink) ); ; try try { { sink sink. .emit emit( (SseEvent SseEvent. .create create( ("{\"type\":\"connected\"}" "{\"type\":\"connected\"}", , MediaTypes MediaTypes. .APPLICATION_JSON APPLICATION_JSON) )) ); ; } } catch catch ( (Exception Exception ignore ignore) ) { {} } } } void void remove remove( (SseSink SseSink sink sink) ) { { sinks sinks. .remove remove( (sink sink) ); ; } } void void broadcastJson broadcastJson( (String String json json) ) { { sinks sinks. .removeIf removeIf( (s s -> -> { { try try { { s s. .emit emit( (SseEvent SseEvent. .create create( (json json, , MediaTypes MediaTypes. .APPLICATION_JSON APPLICATION_JSON) )) ); ; return return false false; ; } } catch catch ( (Exception Exception e e) ) { { return return true true; ; // drop broken sink } // drop broken sink } } }) ); ; } } } } Copyright @ 2025 Oracle and/or its affiliates. SseHub.java 43
  34. Server-Sent Events (SSE) - class final final class class SseRoutes

    SseRoutes { { private private SseRoutes SseRoutes( () ) { {} } static static void void registerRoutes registerRoutes( (HttpRouting HttpRouting. .Builder Builder r r) ) { { // Require login for /events // Require login for /events r r. .any any( ("/events" "/events", , ( (ServerRequest ServerRequest req req, , ServerResponse ServerResponse res res) ) -> -> { { if if ( (! !Auth Auth. .isAuthenticated isAuthenticated( (req req) )) ) { { res res. .status status( (401 401) ). .send send( ("Unauthorized" "Unauthorized") ); ; return return; ; } } res res. .next next( () ); ; } }) ); ; r r. .get get( ("/events" "/events", , ( (req req, , res res) ) -> -> { { . .. .. . Copyright @ 2025 Oracle and/or its affiliates. SseRoutes.java 44
  35. Server-Sent Events (SSE) - script On the static page (index.html)

    we add a small JavaScript snippet to connect to the SSE endpoint and handle incoming messages: // Live updates // Live updates try try { { const const ev ev = = new new EventSource EventSource( ('/events' '/events') ); ; ev ev. .onmessage onmessage = = e e => => { { const const pre pre = = document document. .getElementById getElementById( ('events' 'events') ); ; pre pre. .textContent textContent = = ( (pre pre. .textContent textContent + + '\n' '\n' + + e e. .data data) ). .trim trim( () ). .slice slice( (- -2000 2000) ); ; try try { { const const msg msg = = JSON JSON. .parse parse( (e e. .data data) ); ; if if ( (msg msg. .type type === === 'actor.changed' 'actor.changed') ) load load( () ); ; } } catch catch { {} } } }; ; } } catch catch { {} } Copyright @ 2025 Oracle and/or its affiliates. index.html 45
  36. OCI GenAI Integration • Helidon 4.3 + LangChain4j support •

    Connected to OCI GenAI (LLM models, region-dependent) • Use case: Summarize actor’s career from Sakila DB • Output: HTML snippet enriched with AI insights Copyright @ 2025 Oracle and/or its affiliates. 46
  37. OCI GenAI Integration - dependency < <dependencies dependencies> > <

    <dependency dependency> > < <groupId groupId> >io.helidon.integrations.langchain4j io.helidon.integrations.langchain4j</ </groupId groupId> > < <artifactId artifactId> >helidon-integrations-langchain4j helidon-integrations-langchain4j</ </artifactId artifactId> > </ </dependency dependency> > < <dependency dependency> > < <groupId groupId> >io.helidon.integrations.langchain4j.providers io.helidon.integrations.langchain4j.providers</ </groupId groupId> > < <artifactId artifactId> >helidon-integrations-langchain4j-providers-oci-genai helidon-integrations-langchain4j-providers-oci-genai</ </artifactId artifactId> > </ </dependency dependency> > < <dependency dependency> > < <groupId groupId> >io.helidon.integrations.oci.sdk io.helidon.integrations.oci.sdk</ </groupId groupId> > < <artifactId artifactId> >helidon-integrations-oci-sdk-runtime helidon-integrations-oci-sdk-runtime</ </artifactId artifactId> > </ </dependency dependency> > < <dependency dependency> > < <groupId groupId> >io.helidon.integrations.oci io.helidon.integrations.oci</ </groupId groupId> > < <artifactId artifactId> >helidon-integrations-oci helidon-integrations-oci</ </artifactId artifactId> > </ </dependency dependency> > </ </dependencies dependencies> > Copyright @ 2025 Oracle and/or its affiliates. pom.xml 47
  38. OCI GenAI Integration - con�g The con�guration is done in

    the application.yaml �le: langchain4j langchain4j: : oci-gen-ai oci-gen-ai: : chat-model chat-model: : enabled enabled: : true true region region: : "eu-frankfurt-1" "eu-frankfurt-1" compartment-id compartment-id: : "ocid1.compartment.oc1..xxxxx" "ocid1.compartment.oc1..xxxxx" #model-name: "xai.grok-3" #model-name: "xai.grok-3" model-name model-name: : "meta.llama-3.3-70b-instruct" "meta.llama-3.3-70b-instruct" Copyright @ 2025 Oracle and/or its affiliates. application.yaml 48
  39. OCI GenAI Integration - class • ai.DiscoveryChatService class → encapsulates

    the GenAI interaction • AiRoutes class → de�nes the AI endpoint package package ; ; import import Ai Ai; ; import import SystemMessage SystemMessage; ; @Ai.Service @Ai.Service public public interface interface DiscoveryChatService DiscoveryChatService { { @SystemMessage @SystemMessage( (""" """ Always provides as much information as possible and print the AI model used. Always provides as much information as possible and print the AI model used. Present yourself as Sakila-GenAI Assistant. Present yourself as Sakila-GenAI Assistant. """ """) ) String String chat chat( (String String message message) ); ; } } Copyright @ 2025 Oracle and/or its affiliates. DiscoveryChatService.java main main. .java java. .me me. .test test. .ai ai io io. .helidon helidon. .integrations integrations. .langchain4j langchain4j. . dev dev. .langchain4j langchain4j. .service service. . 49
  40. OCI GenAI Integration - class import import DiscoveryChatService DiscoveryChatService; ;

    final final class class AiRoutes AiRoutes { { private private AiRoutes AiRoutes( () ) { {} } static static void void registerRoutes registerRoutes( (HttpRouting HttpRouting. .Builder Builder r r, , MrsClient MrsClient mrs mrs, , DiscoveryChatService DiscoveryChatService explainer explainer) ) { { r r. .any any( ("/ai/actors/{id}/explain" "/ai/actors/{id}/explain", , ( (ServerRequest ServerRequest req req, , ServerResponse ServerResponse res res) ) -> -> { { if if ( (! !Auth Auth. .isAuthenticated isAuthenticated( (req req) )) ) { { res res. .status status( (401 401) ). .send send( ("Unauthorized" "Unauthorized") ); ; return return; ; } } res res. .next next( () ); ; } }) ); ; r r. .get get( ("/ai/actors/{id}/explain" "/ai/actors/{id}/explain", , ( (req req, , res res) ) -> -> { { String String id id = = req req. .path path( () ). .pathParameters pathParameters( () ). .get get( ("id" "id") ); ; . .. .. . String String actorJson actorJson = = mrs mrs. .get get( ("/sakila/actor/" "/sakila/actor/" + + id id, , null null) ); ; String String prompt prompt = = "Explain this actor record in a HTML snippet. " "Explain this actor record in a HTML snippet. " + + "Highlight first/last name and lastUpdate. Provide a summary of the actor's filmography " "Highlight first/last name and lastUpdate. Provide a summary of the actor's filmography " + + "with dates and languages. Please highlight the best and the worse movie explaining why with details, " "with dates and languages. Please highlight the best and the worse movie explaining why with details, " + + "including rating and rentalRate. Could you also add a chart of the categories of the movies this actor" "including rating and rentalRate. Could you also add a chart of the categories of the movies this actor" + + "played in? Output ONLY HTML (no <html> wrapper).\n\n" "played in? Output ONLY HTML (no <html> wrapper).\n\n" + + actorJson actorJson; ; Copyright @ 2025 Oracle and/or its affiliates. DiscoveryChatService.java main main. .java java. .me me. .test test. .ai ai. . 50
  41. Zero SQL in the App • REST endpoints created for

    all operations • CRUD operations via Helidon + MRS client • No SQL in the codebase • Bug�xes and improvements contributed back to Helidon/MySQL Copyright @ 2025 Oracle and/or its affiliates. 51
  42. MRS Client class . .. .. . public public String

    String get get( (String String path path, , String String rawQuery rawQuery) ) { { . .. .. . public public String String postJson postJson( (String String path path, , String String json json) ) { { . .. .. . public public String String patchJson patchJson( (String String path path, , String String json json) ) { { . .. .. . public public String String putJson putJson( (String String path path, , String String json json) ) { { return return withAuthRetry withAuthRetry( (( () ) -> -> { { HttpClientRequest HttpClientRequest req req = = client client. .put put( () ). .path path( (path path) ). .contentType contentType( (MediaTypes MediaTypes. .APPLICATION_JSON APPLICATION_JSON) ); ; applyCommon applyCommon( (req req) ); ; return return req req. .submit submit( (json json) ); ; } }) ); ; } } public public String String delete delete( (String String path path) ) { { . .. .. . Copyright @ 2025 Oracle and/or its affiliates. MrsClient.java 52
  43. Lessons Learned • Helidon team responsiveness accelerated development • Combining

    REST + SSE + GenAI = lightweight yet powerful • Developers can focus on business logic, not plumbing • Fully functional demo → available on GitHub Copyright @ 2025 Oracle and/or its affiliates. 53
  44. Conclusion • Modern frameworks (Helidon) + REST (MRS) + AI

    (OCI GenAI) • Build powerful apps quickly, without SQL complexity • Future possibilities: extending to other AI tasks, cloud-native apps Copyright @ 2025 Oracle and/or its affiliates. 59
  45. Conclusion • Modern frameworks (Helidon) + REST (MRS) + AI

    (OCI GenAI) • Build powerful apps quickly, without SQL complexity • Future possibilities: extending to other AI tasks, cloud-native apps Copyright @ 2025 Oracle and/or its affiliates. Code available on GitHub: https://github.com/lefred/helidon-mrs-genai 59
  46. Share your to MySQL #mysql #MySQLCommunity Join our slack channel!

    bit.ly/mysql-slack Copyright @ 2025 Oracle and/or its affiliates. 60