{"id":1345,"date":"2021-11-02T11:59:57","date_gmt":"2021-11-02T10:59:57","guid":{"rendered":"https:\/\/www.loicmathieu.fr\/wordpress\/?p=1345"},"modified":"2021-11-02T12:03:27","modified_gmt":"2021-11-02T11:03:27","slug":"quarkus-et-les-google-cloud-functions","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/quarkus-et-les-google-cloud-functions\/","title":{"rendered":"Quarkus and  the Google Cloud Functions"},"content":{"rendered":"<p>Quarkus is a microservice framework designed for the cloud and the containers.<\/p>\n<p>It is designed to have a reduced memory usage and the shortest possible startup time.<\/p>\n<p>It is mainly based on standards (Jakarta EE, Eclipse MicroProfile, &#8230;) and allows the use of mature and widespread Java libraries via its extensions (Hibernate, RESTeasy, Vert.X, Kafka, &#8230;).<\/p>\n<p>Quarkus has been thought for the cloud since its inception, it allows the development of Cloud Ready applications (as defined by the principle of <a href=\"https:\/\/12factor.net\/\" rel=\"noopener\" target=\"_blank\">12 Factors<\/a> applications) and Cloud Native (use of public cloud capabilities to develop your applications).<\/p>\n<p>Quarkus allows among other things the creation of Google Cloud Functions for the development of your applications.<\/p>\n<p>Quarkus allows you to implement a Google Cloud Function of type background or HTTP in several ways:<\/p>\n<ul><li>Via Google Cloud APIs.<\/li>\n\n<li>Via Funqy: a Cloud provider agnostic function development framework.<\/li>\n\n<li>Via one of Quarkus HTTP extensions: RESTEasy (JAX-RS), Vert.x reactive routes, Undertow (Servlet), Spring Web.<\/li>\n<\/ul>\n<h2>Background Function with Google Cloud API<\/h2>\n<p>First , create a Quarkus project with the Quarkus Maven plugin:<\/p>\n<pre>\nmvn io.quarkus:quarkus-maven-plugin:1.12.2.Final:create\n    -DprojectGroupId=org.acme\n    -DprojectArtifactId=google-cloud-functions \\\n    -Dextensions=\"resteasy,google-cloud-functions\"\n<\/pre>\n<p>This Maven command will create a project for you, containing a background function and an HTTP function.<\/p>\n<p>The background function created is as follows:<\/p>\n<pre>\n@ApplicationScoped \/\/1\npublic class HelloWorldBackgroundFunction \n        implements BackgroundFunction { \/\/2\n\n    @Override\n    public void accept(StorageEvent event, Context context) throws Exception { \/\/3\n        System.out.println(\"Receive event on file: \" + event.name);\n    }\n\n    public static class StorageEvent {\n        public String name;\n    }\n}\n<\/pre>\n<ol><li>In order for Quarkus to detect your function, it must be annotated with a CDI annotation.<\/li>\n\n<li>The function uses the Google API, here it extends <code>BackgroundFunction<\/code>.<\/li>\n\n<li>The function will be triggered by an event represented by the <code>StorageEvent<\/code> object, for simplicity I only defined its name property.<\/li>\n<\/ol>\n<p>This function will be triggered by a Google Cloud Storage event, and will display in its logs the name of the object created or updated in Cloud Storage.<\/p>\n<p>As the example comes with two functions, you need to delete the HTTP function that was also created, or select the function to deploy. These steps are explained in the Google Cloud Functions guide <a href=\"https:\/\/quarkus.io\/guides\/gcp-functions#choose-your-function\" rel=\"noopener\" target=\"_blank\">here<\/a>, and omitted for simplicity.<\/p>\n<p>To package the function, you need to use the following Maven command <code>mvn clean package<\/code>. This command will create an uberjar in the <strong>target\/deployment<\/strong> directory that you can then deploy as a Cloud Functions.<\/p>\n<p>To deploy this uberjar, you can use the following gcloud command:<\/p>\n<pre>\ngcloud beta functions deploy quarkus-example-storage\n--entry-point=io.quarkus.gcp.functions.QuarkusBackgroundFunction\n--trigger-resource quarkus-hello\n--trigger-event google.storage.object.finalize\n--runtime=java11 --source=target\/deployment\n<\/pre>\n<p>This command uses as entry point <code>io.quarkus.gcp.functions.QuarkusBackgroundFunction<\/code> and not your function. This entry point will start Quarkus, then locate your function inside the CDI container.<\/p>\n<p>To trigger the function via a Cloud Storage event, we need to define the trigger event <code>google.storage.object.finalize<\/code> and specify a bucket name, here <strong>quarkus-hello<\/strong>. This bucket must have been previously created via <code>gsutil mb gs:\/\/quarkus-hello<\/code> or the Google Cloud Console.<\/p>\n<p>Adding an object to the <strong>quarkus-hello<\/strong> bucket will trigger your function.\nYou can test this with the gsutil command which allows you to upload files to a Cloud Storage bucket:<\/p>\n<pre>\ngsutil cp test.txt gs:\/\/quarkus-hello\n<\/pre>\n<p>Or simulate a trigger via:<\/p>\n<pre>\ngcloud functions call quarkus-example-storage\n--data '{\"name\": \"test.txt\"}'.\n<\/pre>\n<p>Note that we use the default function size, which is 256MB. This is enough for the function container (Jetty) and our Quarkus application. We take advantage of the low memory consumption of Quarkus.<\/p>\n<p>If we look at the logs of the start of our function, we can see that our function takes about 2s to start, of which 1s for Quarkus, and the rest (1s) for the function container (Jetty). We take advantage of the fast startup of Quarkus.<\/p>\n<h2>HTTP Function with Google Cloud API<\/h2>\n<p>In the previously created Quarkus project, an HTTP function was generated which has the following code:<\/p>\n<pre>\n@ApplicationScoped \/\/1\npublic class HelloWorldHttpFunction implements HttpFunction { \/\/2\n\n    @Override\n    public void service(HttpRequest httpRequest, HttpResponse httpResponse) \/\/3\n            throws Exception {\n        Writer writer = httpResponse.getWriter();\n        writer.write(\"Hello World\");\n    }\n}\n<\/pre>\n<ol><li>In order for Quarkus to detect your function, it must be annotated with a CDI annotation.<\/li>\n\n<li>The function uses the Google API, here it extends <code>HttpFunction<\/code>.<\/li>\n\n<li>To implement our function, we have access to the HTTP request and response.<\/li>\n<\/ol>\n<p>This function does a simple Hello World.<\/p>\n<p>To package the function, you need to use the following Maven command:<code>mvn clean package<\/code>. This command will create an uberjar in the <strong>target\/deployment<\/strong> directory that you can then deploy as a Cloud Functions.<\/p>\n<p>To deploy this uberjar you can use the following gcloud command:<\/p>\n<pre>\ngcloud beta functions deploy quarkus-example-http\n--entry-point=io.quarkus.gcp.functions.QuarkusHttpFunction\n--runtime=java11 --trigger-http --source=target\/deployment\n<\/pre>\n<p>This command uses as entry point <code>io.quarkus.gcp.functions.QuarkusHttpFunction<\/code> and not your function. This entry point will start Quarkus and then locate your function in the CDI container.<\/p>\n<p>For more information on background and HTTP functions via the Google API, see the following guide: <a href=\"https:\/\/quarkus.io\/guides\/gcp-functions\" rel=\"noopener\" target=\"_blank\">Quarkus Google Cloud Functions<\/a>.<\/p>\n<h2>Background Function with Funqy<\/h2>\n<p>The background function example we saw earlier has the disadvantage of being dependent on the Google Cloud Functions API. It is therefore not portable from one cloud to another.<\/p>\n<p>This is where <strong>Funqy<\/strong>, the cloud provider agnostic Quarkus function API, comes in. We can rewrite the previous background function via <strong>Funqy<\/strong> as follows:<\/p>\n<pre>\npublic class HelloWorldBackgroundFunction { \/\/1\n\n    @Funq \/\/2\n    public void accept(StorageEvent event) throws Exception { \/\/3\n        System.out.println(\"Receive event on file: \" + event.name);\n    }\n\n    public static class StorageEvent {\n        public String name;\n    }\n}\n<\/pre>\n<ol><li>Your function is no longer dependent on the Google API.<\/li>\n\n<li>The <code>@Funq<\/code> annotation allows you to tell <strong>Funqy<\/strong> that this is the method to call when the function is triggered.<\/li>\n\n<li>The function will be triggered by an event represented by the <code>StorageEvent<\/code> object, for simplicity I only defined its name property.<\/li>\n<\/ol>\n<p>To use <strong>Funqy<\/strong>, you need to replace the extension<code>quarkus-google-cloud-functions<\/code> with the extension <code>quarkus-funqy-google-cloud-functions<\/code>.<\/p>\n<p>After packaging your application with Maven, you can deploy it with gcloud in the same way as before, except you need to use the entry point <code>io.quarkus.funqy.gcp.functions.FunqyBackgroundFunction<\/code>. This gives:<\/p>\n<pre>\ngcloud beta functions deploy quarkus-example-storage\n--entry-point=io.quarkus.funqy.gcp.functions.FunqyBackgroundFunction\n--trigger-resource quarkus-hello\n--trigger-event google.storage.object.finalize\n--runtime=java11 --source=target\/deployment\n<\/pre>\n<p>For more information on <strong>Funqy<\/strong>, see the following guide: <a href=\"https:\/\/quarkus.io\/guides\/funqy-gcp-functions\" rel=\"noopener\" target=\"_blank\">Quarkus Funqy Google Cloud Functions<\/a>.<\/p>\n<h2>HTTP Function with RESTEasy<\/h2>\n<p>The HTTP function example we saw earlier has the disadvantage of being dependent on the Google Cloud Functions API. It is therefore not portable from one cloud to another.<\/p>\n<p>Moreover, the direct manipulation of the request and response objects can be tedious.<\/p>\n<p>To overcome this, Quarkus allows you to use its various HTTP extensions instead of the Google API, your function then becomes agnostic of the cloud provider, and much simpler to write.<\/p>\n<p>The previous example can be rewritten as follows using the <strong>RESTEasy<\/strong> extension:<\/p>\n<pre>\n@Path(\"\/\") \/\/1\npublic class HelloWorldHttpFunction{ \/\/2\n\n    @GET \/\/3\n    @Produces(MediaType.TEXT_PLAIN)\n    public void String() throws Exception {\n        return \"Hello World\";\n    }\n}\n<\/pre>\n<ol><li>Here we use the JAX-RS <code>@Path<\/code> annotation to define the class as a REST resource.<\/li>\n\n<li>Our class no longer depends on the Google Functions API.<\/li>\n\n<li>Our function is implemented via a classic REST operation (we can even define more than one if needed).<\/li>\n<\/ol>\n<p>To use <strong>RESTEasy<\/strong>, you need to replace the <code>quarkus-google-cloud-functions<\/code> extension with the <code>quarkus-google-cloud-functions-http<\/code> extension and add the <strong>RESTEasy<\/strong> extension: <code>quarkus-resteasy-jackson<\/code>.<\/p>\n<p>After packaging your application with Maven, you can deploy it with gcloud in the same way as before except that you need to use the entry point <code>io.quarkus.gcp.functions.http.QuarkusHttpFunction<\/code>. This gives:<\/p>\n<pre>\ngcloud beta functions deploy quarkus-example-http\n--entry-point=io.quarkus.gcp.functions.http.QuarkusHttpFunction\n--runtime=java11 --trigger-http --source=target\/deployment\n<\/pre>\n<p>It is also possible to write HTTP functions with the other HTTP frameworks of Quarkus: reactive routes, Undertow (servlet), Funqy HTTP or Spring Web.<\/p>\n<p>For more information on using HTTP extensions via Cloud Functions, see the following guide: <a href=\"https:\/\/quarkus.io\/guides\/gcp-functions-http\" rel=\"noopener\" target=\"_blank\">Quarkus Google Cloud Function HTTP bindings<\/a>.<\/p>\n<h2>Conclusion<\/h2>\n<p>It is very easy to create deployable functions for Google Cloud with dedicated Quarkus extensions. Moreover Funqy (for brackground functions) and HTTP binding (for HTTP functions) allow you to do it without your code being coupled with the Google Cloud API.<\/p>\n<p>Google Cloud functions are ideal for using Google Cloud services, an extension pack exists to facilitate their uses within Quarkus via the extension pack <a href=\"https:\/\/quarkiverse.github.io\/quarkiverse-docs\/quarkus-google-cloud-services\/main\/index.html\" rel=\"noopener\" target=\"_blank\">Google Cloud Services<\/a> that allows to use BigQuery, BigTable, Firestore, PubSub, SecretManager, Spanner and Storage in a Quarkus application.<\/p>","protected":false},"excerpt":{"rendered":"<p>Quarkus is a microservice framework designed for the cloud and the containers. It is designed to have a reduced memory usage and the shortest possible startup time. It is mainly based on standards (Jakarta EE, Eclipse MicroProfile, &#8230;) and allows the use of mature and widespread Java libraries via its extensions (Hibernate, RESTeasy, Vert.X, Kafka, &#8230;). Quarkus has been thought for the cloud since its inception, it allows the development of Cloud Ready applications (as defined by the principle of&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/quarkus-et-les-google-cloud-functions\/\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[9],"tags":[200,181,179,11,167,182],"class_list":["post-1345","post","type-post","status-publish","format-standard","hentry","category-informatique","tag-faas","tag-function","tag-gcp","tag-java","tag-quarkus","tag-serverless"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":2089,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/deploy-a-quarkus-application-in-cloud-run\/","url_meta":{"origin":1345,"position":0},"title":"Deploy a Quarkus application in Cloud Run","author":"admin","date":"Tuesday December 30th, 2025","format":false,"excerpt":"Quarkus is a microservice development framework designed for the cloud and containers. It is designed to have reduced memory usage and the shortest possible startup time. It is mainly based on standards (Jakarta EE, Eclipse MicroProfile, etc.) and allows the use of mature and widely used Java libraries via its\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1560,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/quarkus-tip-tester-une-fonction-google-cloud\/","url_meta":{"origin":1345,"position":1},"title":"Quarkus Tip: Testing a Google Cloud function","author":"admin","date":"Thursday December 29th, 2022","format":false,"excerpt":"I recently contributed a PR to Quarkus that contains a testing framework for Google Cloud functions. Quarkus supports creating Google Cloud functions three different ways: Using the Google Cloud API. Using a Quarkus HTTP extension: RESTEasy, Reactive routes, Servlet, Spring Web. Using Funqy, the cloud provider agnostic Quarkus function API.\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1440,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/google-cloud-functions-2nd-gen\/","url_meta":{"origin":1345,"position":2},"title":"Google Cloud Functions 2nd gen","author":"admin","date":"Tuesday March 29th, 2022","format":false,"excerpt":"Sorry, this entry is only available in Fran\u00e7ais.","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1960,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/creer-un-chatbot-avec-google-gemini-vertex-ai-et-quarkus\/","url_meta":{"origin":1345,"position":3},"title":"Creating a chatbot with Google Gemini Vertex AI and Quarkus","author":"admin","date":"Friday June 27th, 2025","format":false,"excerpt":"I recently created a Quarkus extension that provides access to Google Vertex AI. In this article, I'm going to use this extension to create a chatbot. The first step is to create a Quarkus project containing the REST and Google Cloud Vertex AI extensions. Here are the extensions to add\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2025-06-27-14-22-26-1024x376.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2025-06-27-14-22-26-1024x376.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2025-06-27-14-22-26-1024x376.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1138,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/ma-deuxieme-annee-chez-zenika\/","url_meta":{"origin":1345,"position":4},"title":"(Fran\u00e7ais) Ma deuxi\u00e8me ann\u00e9e chez Zenika","author":"admin","date":"Thursday September  3rd, 2020","format":false,"excerpt":"Sorry, this entry is only available in Fran\u00e7ais.","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":975,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/devfest-nantes-2019-developper-une-api-cloud-ready-avec-quarkus\/","url_meta":{"origin":1345,"position":5},"title":"(Fran\u00e7ais) Devfest Nantes 2019 &#8211; D\u00e9velopper une API Cloud Ready avec Quarkus","author":"admin","date":"Thursday October 31st, 2019","format":false,"excerpt":"Sorry, this entry is only available in Fran\u00e7ais.","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts\/1345","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/comments?post=1345"}],"version-history":[{"count":0,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts\/1345\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/media?parent=1345"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/categories?post=1345"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/tags?post=1345"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}