{"id":178,"date":"2019-04-02T06:46:26","date_gmt":"2019-04-02T04:46:26","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/"},"modified":"2021-12-23T14:26:21","modified_gmt":"2021-12-23T13:26:21","slug":"microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/","title":{"rendered":"Microservices from dev to deploy, part 1: getting started with Helidon"},"content":{"rendered":"<p><a style=\"width: 300px; height: 110px;\" href=\"https:\/\/developer.oracle.com\/code\/rome-april-2019?source=:ex:nc:::RC_WWMK181101P00041:CodemotionArticle3&amp;SC=:ex:nc:::RC_WWMK181101P00041:CodemotionArticle3&amp;pcode=WWMK181101P00041\"><img decoding=\"async\" class=\"aligncenter wp-image-2474 size-full\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/03\/oracle.jpg\" alt=\"\"><\/a><\/p>\n<p>This article written by Todd Sharp, Cloud Developer Advocate at Oracle, was originally published on <a href=\"https:\/\/blogs.oracle.com\/developers\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon\" target=\"_blank\" rel=\"noopener noreferrer\">Oracle Developers Portal<\/a>.<\/p>\n<p><a style=\"width: 300px; height: 110px;\" href=\"https:\/\/blogs.oracle.com\/developers\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon\"><img decoding=\"async\" class=\"aligncenter wp-image-2474 size-full\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/03\/ocpc_businessrole_dba_is09a32sg.jpg\" alt=\"\"><\/a><\/p>\n<p>Microservices are undoubtedly popular. There have been <a href=\"https:\/\/blogs.oracle.com\/developers\/getting-started-with-microservices-part-one\" target=\"_blank\" rel=\"noopener noreferrer\">plenty<\/a> <a href=\"https:\/\/blogs.oracle.com\/developers\/getting-started-with-microservices-part-two\" target=\"_blank\" rel=\"noopener noreferrer\">of<\/a> <a href=\"https:\/\/blogs.oracle.com\/developers\/getting-started-with-microservices-part-three\" target=\"_blank\" rel=\"noopener noreferrer\">great<\/a> <a href=\"https:\/\/blogs.oracle.com\/developers\/getting-started-with-microservices-part-four\" target=\"_blank\" rel=\"noopener noreferrer\">posts<\/a> on this blog that explain the advantages of using a microservice approach to building applications (or \u201cwhy you should use them\u201d). And the reasons are plentiful: flexibility to allow your <span id=\"urn:batch-analysis-bea08738-7b19-4d94-9ddd-1eb331b73cd3\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">teams<\/span> to implement different services with their language\/framework of choice, independent deployments, and <span id=\"urn:batch-analysis-f1f77ae6-fc2f-4246-89ee-8af0941480c1\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/scalability\">scalability<\/span>, and improved build and test times are among the many factors that make a microservice approach preferable to many dev <span id=\"urn:batch-analysis-ff431b50-e877-49ec-b0e0-5fcbf1f75111\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">teams<\/span> nowadays. It\u2019s really not much of a discussion anymore as <a href=\"https:\/\/siliconangle.com\/2018\/05\/02\/new-study-shows-rapid-growth-microservices-adoption-among-enterprises\/\" target=\"_blank\" rel=\"noopener noreferrer\">studies<\/a> have shown that nearly 86% of respondents believe that a microservice approach will be their default architecture within the next 5 years. As I mentioned, the question of \u201cwhy microservices\u201d has long been answered, so in this short blog series, I\u2019d like to answer the question of \u201chow\u201d to implement microservices in your <span id=\"urn:batch-analysis-0578f0e7-1ef0-41fd-a32d-ec988af58524\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/organization\">organization<\/span>. Specifically, how Oracle technologies can help your dev team implement a maintainable, scalable and easy to test, develop, and deploy solution for your microservice applications.<\/p>\n<p>To keep things interesting I thought I\u2019d come up with a fictional scenario that we can follow as we take this journey. Let\u2019s imagine that a completely fabricated startup called <strong>TechCorp<\/strong> has just secured $150M in seed funding for their brilliant new <span id=\"urn:batch-analysis-3cf5c726-cd36-4a8d-8256-431c378c7f9d\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/project\">project<\/span>. <strong>TechCorp<\/strong>\u2019s founder Lydia is very nostalgic and she longs for the \u201cgood old days\u201d when 56k modems screeched and buzzed their way down the on-ramp to the \u201cinterwebs\u201d and she\u2019s convinced <strong>BigCity Venture Capital<\/strong> that personalized homepages are about to make a comeback in a major way. You remember those, right? Weather, financials, news \u2013 even inspiring quotes and funny cat pictures to brighten your day. With funding secured Lydia set about creating a multinational corporation with several <span id=\"urn:batch-analysis-804b6afc-e0c9-4f7f-adb6-2e496e1e0b41\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">teams<\/span> of \u201crock star\u201d developers across the globe. Lydia and her CTO Raj know all about microservices and plan on having their <span id=\"urn:batch-analysis-c96f23ff-ac78-4bbd-a91e-424b1b2aec41\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">teams<\/span> split up and tackle individual portions of the backend to take advantage of their strengths and ensure a flexible and reliable architecture.<\/p>\n<p><strong>Team #1:<\/strong><br \/>\nLocation: London<br \/>\nTeam Lead: Chris<br \/>\nFocus: Weather Service<br \/>\nLanguage: Groovy<br \/>\nFramework: Oracle Helidon SE with Gradle<\/p>\n<p><strong>Team #2:<\/strong><br \/>\nLocation: Tokyo<br \/>\nTeam Lead: Michiko<br \/>\nFocus: Quote Service<br \/>\nLanguage: Java<br \/>\nFramework: Oracle Helidon MP with Maven<\/p>\n<p><strong>Team #3:<\/strong><br \/>\nLocation: Bangalore<br \/>\nTeam Lead: Murielle<br \/>\nFocus: Stock Service<br \/>\nLanguage: JavaScript\/Node<br \/>\nFramework: Express<\/p>\n<p><strong>Team #4:<\/strong><br \/>\nLocation: Melbourne<br \/>\nTeam Lead: Dominic<br \/>\nFocus: Cat Picture Service<br \/>\nLanguage: Java<br \/>\nFramework Oracle Fn (Serverless)<\/p>\n<p><strong><span id=\"urn:batch-analysis-8e3ae9fb-735b-47ae-85d1-84a355b86527\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">Team<\/span> #5:<\/strong><br \/>\nLocation: Atlanta<br \/>\nTeam Lead: Ava<br \/>\nFocus: Frontend<br \/>\nLanguage: JavaScript\/TypeScript<br \/>\nFramework: Angular 6<\/p>\n<p>As you can see, Lydia has put together quite a globally diverse group of <span id=\"urn:batch-analysis-575d81a5-fa15-4b6d-a89c-4f15b061a7c9\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">teams<\/span> with a wide-ranging set of skills and experience. You\u2019ll also notice some non-Oracle technologies in their selections which you might find odd in a blog post focused on Oracle technology, but that\u2019s indicative of many software companies these days. Rarely do <span id=\"urn:batch-analysis-b60d436e-cb8d-41eb-8549-d3d829978405\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">teams<\/span> focus solely on a single <span id=\"urn:batch-analysis-ac355ada-e963-484e-b604-8725fbfbe455\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/ember_company\">company<\/span>\u2019s stack anymore. While we\u2019d love it if they did, the reality is that <span id=\"urn:batch-analysis-1d16d249-a917-4fa4-ad20-a1df1bc24add\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">teams<\/span> typically have strengths and preferences that come into play. I\u2019ll show you in this series how Oracle\u2019s new open source <a href=\"https:\/\/helidon.io\/#\/\" target=\"_blank\" rel=\"noopener noreferrer\">Helidon<\/a> framework and <a href=\"https:\/\/fnproject.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">Fn Serverless<\/a> project can be leveraged to build microservices and serverless functions, but also how a <span id=\"urn:batch-analysis-7ba7ebfc-496c-4f38-96fc-6c31ba12fea6\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">team<\/span> can deploy their entire stack to Oracle\u2019s cloud regardless of the language or framework used to build the services that comprise their application. We&#8217;ll dive slightly deeper into Helidon than an introductory post, so you might want to first read this introductory <a href=\"https:\/\/medium.com\/oracledevs\/helidon-takes-flight-fb7e9e390e9c\" target=\"_blank\" rel=\"noopener noreferrer\">blog post<\/a> and the <a href=\"https:\/\/helidon.io\/docs\/latest\/#\/about\/01_overview\" target=\"_blank\" rel=\"noopener noreferrer\">tutorial<\/a> before you read the rest of this post.<\/p>\n<p>Let\u2019s begin with Team #1 who has been tasked with building out the backend for retrieving a user\u2019s local weather. They\u2019re a Groovy team, but they\u2019ve <a href=\"https:\/\/medium.com\/oracledevs\/helidon-takes-flight-fb7e9e390e9c\" target=\"_blank\" rel=\"noopener noreferrer\">heard good things<\/a> about Oracle\u2019s new microservice framework Helidon so they\u2019ve chosen to use this new <span id=\"urn:batch-analysis-335eb80b-4a6c-418a-90a1-ac873bfe49b4\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/project\">project<\/span> as an opportunity to learn the new framework and see how well it works with Groovy and Gradle as a build tool. Team lead Chris has read through the Helidon tutorial and created a new application using the <a href=\"https:\/\/helidon.io\/docs\/latest\/#\/about\/01_overview\" target=\"_blank\" rel=\"noopener noreferrer\">quickstart examples<\/a> so his first task is to transform the <span id=\"urn:batch-analysis-97075ba2-6ec5-4fb6-849d-457f27fe2947\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/java\">Java<\/span> application that was created into a Groovy application. The first step for Chris, in this case, is to create a Gradle build file and make sure that it includes all of the necessary Helidon dependencies as well as a Groovy dependency. Chris also adds a \u2018copyLibs\u2019 task to make sure that all of the dependencies end up where they need to when the <span id=\"urn:batch-analysis-30878260-1a80-455d-b6c0-89e584d14618\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/project\">project<\/span> is built. The build.gradle file looks like this:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; padding: 15px;\">\n<pre style=\"margin: 0; line-height: 125%;\">apply <span style=\"color: #9999ff;\">plugin:<\/span> <span style=\"color: #cc3300;\">'java'<\/span>\napply <span style=\"color: #9999ff;\">plugin:<\/span> <span style=\"color: #cc3300;\">'maven'<\/span>\napply <span style=\"color: #9999ff;\">plugin:<\/span> <span style=\"color: #cc3300;\">'groovy'<\/span>\napply <span style=\"color: #9999ff;\">plugin:<\/span> <span style=\"color: #cc3300;\">'application'<\/span>\n \nmainClassName <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">'codes.recursive.weather.Main'<\/span>\n \ngroup <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">'codes.recursive.weather'<\/span>\nversion <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">'1.0-SNAPSHOT'<\/span>\n \ndescription <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"\"\"A simple weather microservice\"\"\"<\/span>\n \nsourceSets<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">main<\/span><span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">resources<\/span><span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">srcDirs<\/span> <span style=\"color: #555555;\">=<\/span> <span style=\"color: #555555;\">[<\/span> <span style=\"color: #cc3300;\">\"src\/main\/groovy\"<\/span><span style=\"color: #555555;\">,<\/span> <span style=\"color: #cc3300;\">\"src\/main\/resources\"<\/span> <span style=\"color: #555555;\">]<\/span>\n \nsourceCompatibility <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1.8<\/span>\ntargetCompatibility <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1.8<\/span>\ntasks<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">withType<\/span><span style=\"color: #555555;\">(<\/span>JavaCompile<span style=\"color: #555555;\">)<\/span> <span style=\"color: #555555;\">{<\/span>\n    options<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">encoding<\/span> <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">'UTF-8'<\/span>\n<span style=\"color: #555555;\">}<\/span>\n \next <span style=\"color: #555555;\">{<\/span>\n    helidonversion <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">'0.10.0'<\/span>\n<span style=\"color: #555555;\">}<\/span>\n \nrepositories <span style=\"color: #555555;\">{<\/span>\n    maven <span style=\"color: #555555;\">{<\/span> url <span style=\"color: #cc3300;\">\"http:\/\/repo.maven.apache.org\/maven2\"<\/span> <span style=\"color: #555555;\">}<\/span>\n    mavenLocal<span style=\"color: #555555;\">()<\/span>\n    mavenCentral<span style=\"color: #555555;\">()<\/span>\n<span style=\"color: #555555;\">}<\/span>\n \nconfigurations <span style=\"color: #555555;\">{<\/span>\n    localGroovyConf\n<span style=\"color: #555555;\">}<\/span>\n \ndependencies <span style=\"color: #555555;\">{<\/span>\n    localGroovyConf <span style=\"color: #cc00ff;\">localGroovy<\/span><span style=\"color: #555555;\">()<\/span>\n    compile <span style=\"color: #cc3300;\">'org.codehaus.groovy:groovy-all:3.0.0-alpha-3'<\/span>\n    compile <span style=\"color: #cc3300;\">\"io.helidon:helidon-bom:${project.helidonversion}\"<\/span>\n    compile <span style=\"color: #cc3300;\">\"io.helidon.webserver:helidon-webserver-bundle:${project.helidonversion}\"<\/span>\n    compile <span style=\"color: #cc3300;\">\"io.helidon.config:helidon-config-yaml:${project.helidonversion}\"<\/span>\n    compile <span style=\"color: #cc3300;\">\"io.helidon.microprofile.metrics:helidon-metrics-se:${project.helidonversion}\"<\/span>\n    compile <span style=\"color: #cc3300;\">\"io.helidon.webserver:helidon-webserver-prometheus:${project.helidonversion}\"<\/span>\n    compile <span style=\"color: #9999ff;\">group:<\/span> <span style=\"color: #cc3300;\">'com.mashape.unirest'<\/span><span style=\"color: #555555;\">,<\/span> <span style=\"color: #9999ff;\">name:<\/span> <span style=\"color: #cc3300;\">'unirest-java'<\/span><span style=\"color: #555555;\">,<\/span> <span style=\"color: #9999ff;\">version:<\/span> <span style=\"color: #cc3300;\">'1.4.9'<\/span>\n    testCompile <span style=\"color: #cc3300;\">'org.junit.jupiter:junit-jupiter-api:5.1.0'<\/span>\n<span style=\"color: #555555;\">}<\/span>\n \n<span style=\"color: #0099ff; font-style: italic;\">\/\/ define a custom task to copy all dependencies in the runtime classpath<\/span>\n<span style=\"color: #0099ff; font-style: italic;\">\/\/ into build\/libs\/libs<\/span>\n<span style=\"color: #0099ff; font-style: italic;\">\/\/ uses built-in Copy<\/span>\ntask <span style=\"color: #cc00ff;\">copyLibs<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #9999ff;\">type:<\/span> Copy<span style=\"color: #555555;\">)<\/span> <span style=\"color: #555555;\">{<\/span>\n  from configurations<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">runtime<\/span>\n  into <span style=\"color: #cc3300;\">'build\/libs\/libs'<\/span>\n<span style=\"color: #555555;\">}<\/span>\n \n<span style=\"color: #0099ff; font-style: italic;\">\/\/ add it as a dependency of built-in task 'assemble'<\/span>\ncopyLibs<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">dependsOn<\/span> jar\ncopyDocker<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">dependsOn<\/span> jar\ncopyK8s<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">dependsOn<\/span> jar\nassemble<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">dependsOn<\/span> copyLibs\nassemble<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">dependsOn<\/span> copyDocker\nassemble<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">dependsOn<\/span> copyK8s\n \n<span style=\"color: #0099ff; font-style: italic;\">\/\/ default jar configuration<\/span>\n<span style=\"color: #0099ff; font-style: italic;\">\/\/ set the main classpath<\/span>\njar <span style=\"color: #555555;\">{<\/span>\n  archiveName <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"${project.name}.jar\"<\/span>\n    manifest <span style=\"color: #555555;\">{<\/span>\n        attributes <span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">'Main-Class'<\/span><span style=\"color: #555555;\">:<\/span> <span style=\"color: #cc3300;\">\"${mainClassName}\"<\/span><span style=\"color: #555555;\">,<\/span>\n                <span style=\"color: #cc3300;\">'Class-Path'<\/span><span style=\"color: #555555;\">:<\/span> configurations<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">runtime<\/span><span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">files<\/span><span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">collect<\/span> <span style=\"color: #555555;\">{<\/span> <span style=\"color: #cc3300;\">\"libs\/$it.name\"<\/span> <span style=\"color: #555555;\">}.<\/span><span style=\"color: #330099;\">join<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">' '<\/span><span style=\"color: #555555;\">)<\/span>\n               <span style=\"color: #555555;\">)<\/span>\n    <span style=\"color: #555555;\">}<\/span>\n<span style=\"color: #555555;\">}<\/span>\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>With the build script set up Chris\u2019 team goes about building the application. Helidon SE makes it pretty easy to build out a simple service. To get started you only really need a few classes: A Main.groovy (notice that the Gradle script indentifies the mainClassName with a path to Main.groovy) which creates the server, sets up routing, configures error handling and optionally sets up metrics for the server. Here\u2019s the entire Main.groovy:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; padding: 15px;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">final<\/span> <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Main<\/span> <span style=\"color: #555555;\">{<\/span>\n \n    <span style=\"color: #006699; font-weight: bold;\">private<\/span> <span style=\"color: #cc00ff;\">Main<\/span><span style=\"color: #555555;\">()<\/span> <span style=\"color: #555555;\">{<\/span> <span style=\"color: #555555;\">}<\/span>\n \n    <span style=\"color: #006699; font-weight: bold;\">private<\/span> <span style=\"color: #006699; font-weight: bold;\">static<\/span> Routing <span style=\"color: #cc00ff;\">createRouting<\/span><span style=\"color: #555555;\">()<\/span> <span style=\"color: #555555;\">{<\/span>\n        MetricsSupport metricsSupport <span style=\"color: #555555;\">=<\/span> MetricsSupport<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">create<\/span><span style=\"color: #555555;\">()<\/span>\n \n        MetricRegistry registry <span style=\"color: #555555;\">=<\/span> RegistryFactory\n                <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">getRegistryFactory<\/span><span style=\"color: #555555;\">()<\/span>\n                <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">get<\/span><span style=\"color: #555555;\">()<\/span>\n                <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">getRegistry<\/span><span style=\"color: #555555;\">(<\/span>MetricRegistry<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">Type<\/span><span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">APPLICATION<\/span><span style=\"color: #555555;\">)<\/span>\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> Routing<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">builder<\/span><span style=\"color: #555555;\">()<\/span>\n                <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">register<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"\/weather\"<\/span><span style=\"color: #555555;\">,<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> WeatherService<span style=\"color: #555555;\">())<\/span>\n                <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">register<\/span><span style=\"color: #555555;\">(<\/span>metricsSupport<span style=\"color: #555555;\">)<\/span>\n                <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">error<\/span><span style=\"color: #555555;\">(<\/span> NotFoundException<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">class<\/span><span style=\"color: #555555;\">,<\/span> <span style=\"color: #555555;\">{<\/span>req<span style=\"color: #555555;\">,<\/span> res<span style=\"color: #555555;\">,<\/span> ex <span style=\"color: #555555;\">-&gt;<\/span>\n                    res<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">headers<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">contentType<\/span><span style=\"color: #555555;\">(<\/span>MediaType<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">APPLICATION_JSON<\/span><span style=\"color: #555555;\">)<\/span>\n                    res<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">status<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #ff6600;\">404<\/span><span style=\"color: #555555;\">).<\/span><span style=\"color: #330099;\">send<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #006699; font-weight: bold;\">new<\/span> JsonGenerator<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">Options<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">build<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">toJson<\/span><span style=\"color: #555555;\">(<\/span>ex<span style=\"color: #555555;\">))<\/span>\n                <span style=\"color: #555555;\">})<\/span>\n                <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">error<\/span><span style=\"color: #555555;\">(<\/span> Exception<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">class<\/span><span style=\"color: #555555;\">,<\/span> <span style=\"color: #555555;\">{<\/span>req<span style=\"color: #555555;\">,<\/span> res<span style=\"color: #555555;\">,<\/span> ex <span style=\"color: #555555;\">-&gt;<\/span>\n                    ex<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">printStackTrace<\/span><span style=\"color: #555555;\">()<\/span>\n                    res<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">headers<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">contentType<\/span><span style=\"color: #555555;\">(<\/span>MediaType<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">APPLICATION_JSON<\/span><span style=\"color: #555555;\">)<\/span>\n                    res<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">status<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #ff6600;\">500<\/span><span style=\"color: #555555;\">).<\/span><span style=\"color: #330099;\">send<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #006699; font-weight: bold;\">new<\/span> JsonGenerator<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">Options<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">build<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">toJson<\/span><span style=\"color: #555555;\">(<\/span>ex<span style=\"color: #555555;\">))<\/span>\n                <span style=\"color: #555555;\">})<\/span>\n                <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">build<\/span><span style=\"color: #555555;\">()<\/span>\n    <span style=\"color: #555555;\">}<\/span>\n \n    <span style=\"color: #006699; font-weight: bold;\">static<\/span> <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">main<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #006699; font-weight: bold;\">final<\/span> String<span style=\"color: #555555;\">[]<\/span> args<span style=\"color: #555555;\">)<\/span> <span style=\"color: #006699; font-weight: bold;\">throws<\/span> IOException <span style=\"color: #555555;\">{<\/span>\n        startServer<span style=\"color: #555555;\">()<\/span>\n    <span style=\"color: #555555;\">}<\/span>\n \n    <span style=\"color: #006699; font-weight: bold;\">protected<\/span> <span style=\"color: #006699; font-weight: bold;\">static<\/span> WebServer <span style=\"color: #cc00ff;\">startServer<\/span><span style=\"color: #555555;\">()<\/span> <span style=\"color: #006699; font-weight: bold;\">throws<\/span> IOException <span style=\"color: #555555;\">{<\/span>\n \n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ load logging configuration<\/span>\n        LogManager<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">getLogManager<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">readConfiguration<\/span><span style=\"color: #555555;\">(<\/span>\n                Main<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">class<\/span><span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">getResourceAsStream<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"\/logging.properties\"<\/span><span style=\"color: #555555;\">))<\/span>\n \n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ By default this will pick up application.yaml from the classpath<\/span>\n        Config config <span style=\"color: #555555;\">=<\/span> Config<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">create<\/span><span style=\"color: #555555;\">()<\/span>\n \n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ Get webserver config from the \"server\" section of application.yaml<\/span>\n        ServerConfiguration serverConfig <span style=\"color: #555555;\">=<\/span>\n                ServerConfiguration<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">fromConfig<\/span><span style=\"color: #555555;\">(<\/span>config<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">get<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"server\"<\/span><span style=\"color: #555555;\">))<\/span>\n \n        WebServer server <span style=\"color: #555555;\">=<\/span> WebServer<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">create<\/span><span style=\"color: #555555;\">(<\/span>serverConfig<span style=\"color: #555555;\">,<\/span> createRouting<span style=\"color: #555555;\">())<\/span>\n \n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ Start the server and print some info.<\/span>\n        server<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">start<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">thenAccept<\/span><span style=\"color: #555555;\">(<\/span> <span style=\"color: #555555;\">{<\/span> NettyWebServer ws <span style=\"color: #555555;\">-&gt;<\/span>\n            println <span style=\"color: #cc3300;\">\"<span id=\"urn:batch-analysis-035f8ad4-39e5-4108-8544-10fdbd3e908c\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/web_server\">Web server<\/span> is running at <span id=\"urn:batch-analysis-a04a97d3-ef56-4b38-9933-b7cf389a877c\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/post_http\">http<\/span>:\/\/${config.get(\"<\/span>server<span style=\"color: #cc3300;\">\").get(\"<\/span>host<span style=\"color: #cc3300;\">\").asString()}:${config.get(\"<\/span>server<span style=\"color: #cc3300;\">\").get(\"<\/span>port<span style=\"color: #cc3300;\">\").asString()}\"<\/span>\n        <span style=\"color: #555555;\">})<\/span>\n \n        <span style=\"color: #0099ff; font-style: italic;\">\/\/ Server threads are not demon. NO need to block. Just react.<\/span>\n        server<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">whenShutdown<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">thenRun<\/span><span style=\"color: #555555;\">({<\/span> it <span style=\"color: #555555;\">-&gt;<\/span>\n            Unirest<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">shutdown<\/span><span style=\"color: #555555;\">()<\/span>\n            println <span style=\"color: #cc3300;\">\"<span id=\"urn:batch-analysis-055b8846-5cd4-452f-b4cc-9cf916c03b3b\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/web_server\">Web server<\/span> has been shut down.  Goodbye!\"<\/span>\n        <span style=\"color: #555555;\">})<\/span>\n \n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> server\n    <span style=\"color: #555555;\">}<\/span>\n<span style=\"color: #555555;\">}<\/span>\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Heldion SE uses a YAML file located in src\/main\/resources (named application.yaml) for configuration. You can store server related config, as well as any application variables in this file. Chris\u2019 team puts a few variables related to the API in this file:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; padding: 15px;\">\n<pre style=\"margin: 0; line-height: 125%;\">app:\n  apiBaseUrl: <span style=\"color: #cc3300;\">\"https:\/\/api.openweathermap.org\/data\/2.5\"<\/span>\n  apiKey: <span style=\"color: #cc3300;\">\"[redacted]\"<\/span>\n \nserver:\n  port: 8080\n  host: 0.0.0.0\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Looking back at the Main class, notice on line 13 where the endpoint \u201c\/weather\u201d is registered and pointed at the WeatherService. That\u2019s the class that\u2019ll do all the heavy lifting when it comes to getting weather data. Helidon SE services implement the Service interface. This class has an update() method that is used to establish sub-routes for the given service and point those sub-routes at private methods of the service class. Here\u2019s what Chris\u2019 team came up with for the update() method:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; padding: 15px;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">update<\/span><span style=\"color: #555555;\">(<\/span>Routing<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">Rules<\/span> rules<span style=\"color: #555555;\">)<\/span> <span style=\"color: #555555;\">{<\/span>\n    rules\n        <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">any<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #006699; font-weight: bold;\">this<\/span><span style=\"color: #555555;\">::<\/span>countAccess <span style=\"color: #006699; font-weight: bold;\">as<\/span> Handler<span style=\"color: #555555;\">)<\/span>\n        <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">get<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"\/current\/city\/{city}\"<\/span><span style=\"color: #555555;\">,<\/span> <span style=\"color: #006699; font-weight: bold;\">this<\/span><span style=\"color: #555555;\">::<\/span>getByLocation <span style=\"color: #006699; font-weight: bold;\">as<\/span> Handler<span style=\"color: #555555;\">)<\/span>\n        <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">get<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"\/current\/id\/{id}\"<\/span><span style=\"color: #555555;\">,<\/span> <span style=\"color: #006699; font-weight: bold;\">this<\/span><span style=\"color: #555555;\">::<\/span>getById <span style=\"color: #006699; font-weight: bold;\">as<\/span> Handler<span style=\"color: #555555;\">)<\/span>\n        <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">get<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"\/current\/lat\/{lat}\/lon\/{lon}\"<\/span><span style=\"color: #555555;\">,<\/span> <span style=\"color: #006699; font-weight: bold;\">this<\/span><span style=\"color: #555555;\">::<\/span>getByLatLon <span style=\"color: #006699; font-weight: bold;\">as<\/span> Handler<span style=\"color: #555555;\">)<\/span>\n        <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">get<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"\/current\/zip\/{zip}\"<\/span><span style=\"color: #555555;\">,<\/span> <span style=\"color: #006699; font-weight: bold;\">this<\/span><span style=\"color: #555555;\">::<\/span>getByZip <span style=\"color: #006699; font-weight: bold;\">as<\/span> Handler<span style=\"color: #555555;\">)<\/span>\n<span style=\"color: #555555;\">}<\/span>\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Chris\u2019 team creates 4 different routes under \u201c\/weather\u201d giving the consumer the ability to get the current weather in 4 separate ways (by city, id, lat\/lon or zip code). Note that since we\u2019re using Groovy we have to cast the method references as io.helidon.webserver.Handler or we\u2019ll get an exception. We\u2019ll take a quick look at just one of those methods, getByZip():<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; padding: 15px;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">private<\/span> <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">getByZip<\/span><span style=\"color: #555555;\">(<\/span>ServerRequest request<span style=\"color: #555555;\">,<\/span> ServerResponse response<span style=\"color: #555555;\">)<\/span> <span style=\"color: #555555;\">{<\/span>\n    <span style=\"color: #007788; font-weight: bold;\">def<\/span> zip <span style=\"color: #555555;\">=<\/span> request<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">path<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">param<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"zip\"<\/span><span style=\"color: #555555;\">)<\/span>\n    <span style=\"color: #007788; font-weight: bold;\">def<\/span> weather <span style=\"color: #555555;\">=<\/span> getWeather<span style=\"color: #555555;\">([<\/span> <span style=\"color: #555555;\">(<\/span>ZIP<span style=\"color: #555555;\">):<\/span> zip <span style=\"color: #555555;\">])<\/span>\n    response<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">headers<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">contentType<\/span><span style=\"color: #555555;\">(<\/span>MediaType<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">APPLICATION_JSON<\/span><span style=\"color: #555555;\">)<\/span>\n    response<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">send<\/span><span style=\"color: #555555;\">(<\/span>weather<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">getBody<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">getObject<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">toString<\/span><span style=\"color: #555555;\">())<\/span>\n<span style=\"color: #555555;\">}<\/span>\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The getByZip() method grabs the zip parameter from the request and calls getWeather(), which uses a client library called <a href=\"http:\/\/unirest.io\/java.html\" target=\"_blank\" rel=\"noopener noreferrer\">Unirest<\/a> to make an HTTP call to the chosen weather API and returns the current weather to getByZip() which sends the response to the browser as <span id=\"urn:batch-analysis-9534afc9-c7f7-4c26-a4dd-9e5b65ec3b9d\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/json\">JSON<\/span>:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; padding: 15px;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">private<\/span> HttpResponse<span style=\"color: #555555;\">&lt;<\/span>JsonNode<span style=\"color: #555555;\">&gt;<\/span> getWeather<span style=\"color: #555555;\">(<\/span>Map params<span style=\"color: #555555;\">)<\/span> <span style=\"color: #555555;\">{<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> Unirest\n        <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">get<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"${baseUrl}\/weather?${params.collect { it }.join('&amp;')}&amp;appid=${apiKey}\"<\/span><span style=\"color: #555555;\">)<\/span>\n        <span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">asJson<\/span><span style=\"color: #555555;\">()<\/span>\n<span style=\"color: #555555;\">}<\/span>\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>As you can see, each service method gets passed two arguments when called by the router \u2013 the request and response (as you might have guessed if you\u2019ve worked with a microservice framework before). These arguments allow the developer to grab URL parameters, form <span id=\"urn:batch-analysis-4eefedce-091c-4879-b521-d809048ae07e\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/data\">data<\/span> or headers from the request and set the status, body or headers into the response as necessary. Once the <span id=\"urn:batch-analysis-0b352020-704d-402e-a2f3-34d52c3c9781\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">team<\/span> builds out the entire weather service they are ready to execute the Gradle run task to see everything working in the browser.<\/p>\n<p><a style=\"width: 300px; height: 110px;\" href=\"https:\/\/blogs.oracle.com\/developers\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon\"><img decoding=\"async\" class=\"aligncenter wp-image-2474 size-full\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/03\/weather_response.png\" alt=\"\"><\/a><\/p>\n<p>Cloudy in London? A shocking weather development!<\/p>\n<p>There\u2019s obviously more to Helidon SE, but as you can see it doesn\u2019t take a lot of code to get a basic microservice up and running. We\u2019ll take a look at deploying the services in a later post, but Helidon makes that step trivial with baked in support for generating Dockerfiles and Kubernetes config files.<\/p>\n<p>Let\u2019s switch gears now and look at Michiko\u2019s team who was tasked with building out a backend to return random quotes since no personalized homepage would be complete without such a <span id=\"urn:batch-analysis-2e352346-43c2-4761-85f7-0a671a257c1b\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/feature_machine_learning\">feature<\/span>. The Tokyo team prefers to code in <span id=\"urn:batch-analysis-30e14b45-7196-4ed9-89b2-3f83523de50a\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/java\">Java<\/span> and they use Maven to manage compilation and dependencies. They are quite familiar with the <a href=\"https:\/\/microprofile.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">Microprofile<\/a> family of APIs. Michiko and team also decided to use Helidon, but with their Microprofile expertise, they decided to go with Helidon MP over the more reactive functional style of SE because it provides recognizable APIs like JAX-RS and CDI that they have been using for years. Like Chris\u2019 team, they rapidly scaffold out a skeleton application with the MP <a href=\"https:\/\/helidon.io\/docs\/latest\/#\/about\/01_overview\" target=\"_blank\" rel=\"noopener noreferrer\">quickstart archetype<\/a> and set out configuring their Main.java class. The main method of that class calls startServer() which is slightly different from the SE method, but accomplishes the same task \u2013 starting up the application server using a config file (this one named microprofile-config.properties and located in \/src\/main\/resources\/META-INF):<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; padding: 15px;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">protected<\/span> <span style=\"color: #006699; font-weight: bold;\">static<\/span> Server <span style=\"color: #cc00ff;\">startServer<\/span><span style=\"color: #555555;\">()<\/span> <span style=\"color: #006699; font-weight: bold;\">throws<\/span> IOException <span style=\"color: #555555;\">{<\/span>\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ load logging configuration<\/span>\n    LogManager<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">getLogManager<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">readConfiguration<\/span><span style=\"color: #555555;\">(<\/span>\n            Main<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">class<\/span><span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">getResourceAsStream<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"\/logging.properties\"<\/span><span style=\"color: #555555;\">));<\/span>\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ Server will automatically pick up configuration from<\/span>\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ microprofile-config.properties<\/span>\n    Server server <span style=\"color: #555555;\">=<\/span> Server<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">create<\/span><span style=\"color: #555555;\">();<\/span>\n    server<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">start<\/span><span style=\"color: #555555;\">();<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> server<span style=\"color: #555555;\">;<\/span>\n<span style=\"color: #555555;\">}<\/span>\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Next, they create a beans.xml file in \/src\/main\/resources\/META-INF so the CDI implementation can pick up their classes:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; padding: 15px;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">&lt;!--?xml version=\"1.0\" encoding=\"UTF-8\"?--&gt;<\/span>\n<span style=\"color: #330099; font-weight: bold;\">&lt;beans&gt;<\/span>\n<span style=\"color: #330099; font-weight: bold;\">&lt;\/beans&gt;<\/span>\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Create the JAX-RS application, adding the resource class(es) as needed:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; padding: 15px;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #9999ff;\">@ApplicationScoped<\/span>\n<span style=\"color: #9999ff;\">@ApplicationPath<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"\/\"<\/span><span style=\"color: #555555;\">)<\/span>\n<span style=\"color: #006699; font-weight: bold;\">public<\/span> <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">QuoteApplication<\/span> <span style=\"color: #006699; font-weight: bold;\">extends<\/span> Application <span style=\"color: #555555;\">{<\/span>\n    <span style=\"color: #9999ff;\">@Override<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">public<\/span> Set<span style=\"color: #555555;\">&lt;<\/span>Class<span style=\"color: #555555;\">&lt;?&gt;&gt;<\/span> getClasses<span style=\"color: #555555;\">()<\/span> <span style=\"color: #555555;\">{<\/span>\n        Set<span style=\"color: #555555;\">&lt;<\/span>Class<span style=\"color: #555555;\">&lt;?&gt;&gt;<\/span> set <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> HashSet<span style=\"color: #555555;\">&lt;&gt;();<\/span>\n        set<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">add<\/span><span style=\"color: #555555;\">(<\/span>QuoteResource<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">class<\/span><span style=\"color: #555555;\">);<\/span>\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> Collections<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">unmodifiableSet<\/span><span style=\"color: #555555;\">(<\/span>set<span style=\"color: #555555;\">);<\/span>\n    <span style=\"color: #555555;\">}<\/span>\n<span style=\"color: #555555;\">}<\/span>\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>And create the QuoteResource class:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; padding: 15px;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #9999ff;\">@Path<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"\/quote\"<\/span><span style=\"color: #555555;\">)<\/span>\n<span style=\"color: #9999ff;\">@RequestScoped<\/span>\n<span style=\"color: #006699; font-weight: bold;\">public<\/span> <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">QuoteResource<\/span> <span style=\"color: #555555;\">{<\/span>\n \n    <span style=\"color: #006699; font-weight: bold;\">private<\/span> <span style=\"color: #006699; font-weight: bold;\">static<\/span> String apiBaseUrl <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">null<\/span><span style=\"color: #555555;\">;<\/span>\n \n    <span style=\"color: #9999ff;\">@Inject<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">public<\/span> <span style=\"color: #cc00ff;\">QuoteResource<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #9999ff;\">@ConfigProperty<\/span><span style=\"color: #555555;\">(<\/span>name <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"app.api.baseUrl\"<\/span><span style=\"color: #555555;\">)<\/span> <span style=\"color: #006699; font-weight: bold;\">final<\/span> String apiBaseUrl<span style=\"color: #555555;\">)<\/span> <span style=\"color: #555555;\">{<\/span>\n        <span style=\"color: #006699; font-weight: bold;\">if<\/span> <span style=\"color: #555555;\">(<\/span><span style=\"color: #006699; font-weight: bold;\">this<\/span><span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">apiBaseUrl<\/span> <span style=\"color: #555555;\">==<\/span> <span style=\"color: #006699; font-weight: bold;\">null<\/span><span style=\"color: #555555;\">)<\/span> <span style=\"color: #555555;\">{<\/span>\n            <span style=\"color: #006699; font-weight: bold;\">this<\/span><span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">apiBaseUrl<\/span> <span style=\"color: #555555;\">=<\/span> apiBaseUrl<span style=\"color: #555555;\">;<\/span>\n        <span style=\"color: #555555;\">}<\/span>\n    <span style=\"color: #555555;\">}<\/span>\n \n    <span style=\"color: #9999ff;\">@SuppressWarnings<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"checkstyle:designforextension\"<\/span><span style=\"color: #555555;\">)<\/span>\n    <span style=\"color: #9999ff;\">@Path<\/span><span style=\"color: #555555;\">(<\/span><span style=\"color: #cc3300;\">\"\/random\"<\/span><span style=\"color: #555555;\">)<\/span>\n    <span style=\"color: #9999ff;\">@GET<\/span>\n    <span style=\"color: #9999ff;\">@Produces<\/span><span style=\"color: #555555;\">(<\/span>MediaType<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">APPLICATION_JSON<\/span><span style=\"color: #555555;\">)<\/span>\n    <span style=\"color: #006699; font-weight: bold;\">public<\/span> String <span style=\"color: #cc00ff;\">getRandomQuote<\/span><span style=\"color: #555555;\">()<\/span> <span style=\"color: #006699; font-weight: bold;\">throws<\/span> UnirestException <span style=\"color: #555555;\">{<\/span>\n        String url <span style=\"color: #555555;\">=<\/span> apiBaseUrl <span style=\"color: #555555;\">+<\/span> <span style=\"color: #cc3300;\">\"\/posts?filter[orderby]=rand&amp;filter[posts_per_page]=1\"<\/span><span style=\"color: #555555;\">;<\/span>\n        HttpResponse<span style=\"color: #555555;\">&lt;<\/span>JsonNode<span style=\"color: #555555;\">&gt;<\/span> quote <span style=\"color: #555555;\">=<\/span> Unirest<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">get<\/span><span style=\"color: #555555;\">(<\/span>url<span style=\"color: #555555;\">).<\/span><span style=\"color: #330099;\">asJson<\/span><span style=\"color: #555555;\">();<\/span>\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> quote<span style=\"color: #555555;\">.<\/span><span style=\"color: #330099;\">getBody<\/span><span style=\"color: #555555;\">().<\/span><span style=\"color: #330099;\">toString<\/span><span style=\"color: #555555;\">();<\/span>\n    <span style=\"color: #555555;\">}<\/span>\n \n<span style=\"color: #555555;\">}<\/span>\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Notice the use of constructor injection to get a configuration property and the simple annotations for the path, HTTP method and content type of the response. The getRandomQuote() method again uses Unirest to make a call to the quote API and return the result as a JSON string. Running the mvn package task and executing the resulting JAR starts the application running and results in the following:<\/p>\n<p><a style=\"width: 300px; height: 110px;\" href=\"https:\/\/blogs.oracle.com\/developers\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon\"><img decoding=\"async\" class=\"aligncenter wp-image-2474 size-full\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/03\/quote_response.png\" alt=\"\"><\/a><\/p>\n<p>Michiko\u2019s team has successfully built the initial implementation of their quote microservice on a flexible foundation that will allow the service to grow with time as the user base expands and additional funding rolls in from the excited investors! As with the SE version, Helidon MP generates a Dockerfile and Kubernetes app.yaml file to assist the <span id=\"urn:batch-analysis-e3a70d6f-b2d7-44ab-9b0a-f4726b98accc\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">team<\/span> with deployment. We\u2019ll look at deployment in a later post in this series.<\/p>\n<p>In this post, we talked about a fictitious startup getting into microservices for their heavily funded internet homepage application. We looked at the Helidon microservice framework which provides a reactive, functional style version as well as a Microprofile version more suited to <span id=\"urn:batch-analysis-f94ffb95-2065-4c65-8958-f24d47111be6\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/java\">Java<\/span> EE developers who are comfortable with JAX-RS and CDI. Lydia\u2019s teams are moving rapidly to get their backend architecture built out and are well on their way to implementing her vision for <strong>TechCorp<\/strong>. In the next post, we\u2019ll look at how Murielle and Dominic\u2019s teams build out their services and in future posts we\u2019ll see how all of the <span id=\"urn:batch-analysis-f7a9ea93-43f8-429a-8d71-07ef48e43bfc\" class=\"textannotation disambiguated wl-no-link wl-other\" itemid=\"http:\/\/data.wordlift.io\/wl01770\/entity\/team\">teams<\/span> ultimately test and deploy the services into production.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article written by Todd Sharp, Cloud Developer Advocate at Oracle, was originally published on Oracle Developers Portal. Microservices are undoubtedly popular. There have been plenty of great posts on this blog that explain the advantages of using a microservice approach to building applications (or \u201cwhy you should use them\u201d). And the reasons are plentiful:&#8230; <a class=\"more-link\" href=\"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/\">Read more<\/a><\/p>\n","protected":false},"author":64,"featured_media":179,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[3355],"tags":[],"collections":[],"class_list":{"0":"post-178","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-microservices","8":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Microservices from dev to deploy, part 1: getting started with Helidon - Codemotion Magazine<\/title>\n<meta name=\"description\" content=\"Codemotion and Facebook organized the Tech Leadership Training boot camp, heres a personal reportage from one of our attendees.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Microservices from dev to deploy, part 1: getting started with Helidon\" \/>\n<meta property=\"og:description\" content=\"Codemotion and Facebook organized the Tech Leadership Training boot camp, heres a personal reportage from one of our attendees.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2019-04-02T04:46:26+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-12-23T13:26:21+00:00\" \/>\n<meta name=\"author\" content=\"Codemotion\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png\" \/>\n<meta name=\"twitter:creator\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Codemotion\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/\"},\"author\":{\"name\":\"Codemotion\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/person\\\/201bb98b02412383686cced7521b861c\"},\"headline\":\"Microservices from dev to deploy, part 1: getting started with Helidon\",\"datePublished\":\"2019-04-02T04:46:26+00:00\",\"dateModified\":\"2021-12-23T13:26:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/\"},\"wordCount\":1730,\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/1_jJv-QPlVbKu0kkRrD5gM9A.png\",\"articleSection\":[\"Microservices\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/\",\"name\":\"Microservices from dev to deploy, part 1: getting started with Helidon - Codemotion Magazine\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/1_jJv-QPlVbKu0kkRrD5gM9A.png\",\"datePublished\":\"2019-04-02T04:46:26+00:00\",\"dateModified\":\"2021-12-23T13:26:21+00:00\",\"description\":\"Codemotion and Facebook organized the Tech Leadership Training boot camp, heres a personal reportage from one of our attendees.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/1_jJv-QPlVbKu0kkRrD5gM9A.png\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/1_jJv-QPlVbKu0kkRrD5gM9A.png\",\"width\":816,\"height\":401},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Microservices\",\"item\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/microservices\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Microservices from dev to deploy, part 1: getting started with Helidon\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#website\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/codemotionlogo.png\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/Codemotion.Italy\\\/\",\"https:\\\/\\\/x.com\\\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/person\\\/201bb98b02412383686cced7521b861c\",\"name\":\"Codemotion\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/cropped-codemotionlogo-150x150.png\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/cropped-codemotionlogo-150x150.png\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/cropped-codemotionlogo-150x150.png\",\"caption\":\"Codemotion\"},\"description\":\"Articles wirtten by the Codemotion staff. Tech news, inspiration, latest treends in software development and more.\",\"sameAs\":[\"https:\\\/\\\/x.com\\\/CodemotionIT\"],\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/author\\\/codemotion-2\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Microservices from dev to deploy, part 1: getting started with Helidon - Codemotion Magazine","description":"Codemotion and Facebook organized the Tech Leadership Training boot camp, heres a personal reportage from one of our attendees.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/","og_locale":"en_US","og_type":"article","og_title":"Microservices from dev to deploy, part 1: getting started with Helidon","og_description":"Codemotion and Facebook organized the Tech Leadership Training boot camp, heres a personal reportage from one of our attendees.","og_url":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2019-04-02T04:46:26+00:00","article_modified_time":"2021-12-23T13:26:21+00:00","author":"Codemotion","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png","twitter_creator":"@CodemotionIT","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"Codemotion","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/"},"author":{"name":"Codemotion","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/201bb98b02412383686cced7521b861c"},"headline":"Microservices from dev to deploy, part 1: getting started with Helidon","datePublished":"2019-04-02T04:46:26+00:00","dateModified":"2021-12-23T13:26:21+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/"},"wordCount":1730,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png","articleSection":["Microservices"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/","url":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/","name":"Microservices from dev to deploy, part 1: getting started with Helidon - Codemotion Magazine","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png","datePublished":"2019-04-02T04:46:26+00:00","dateModified":"2021-12-23T13:26:21+00:00","description":"Codemotion and Facebook organized the Tech Leadership Training boot camp, heres a personal reportage from one of our attendees.","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png","width":816,"height":401},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/microservices\/microservices-from-dev-to-deploy-part-1-getting-started-with-helidon-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"Microservices","item":"https:\/\/www.codemotion.com\/magazine\/microservices\/"},{"@type":"ListItem","position":3,"name":"Microservices from dev to deploy, part 1: getting started with Helidon"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/201bb98b02412383686cced7521b861c","name":"Codemotion","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/cropped-codemotionlogo-150x150.png","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/cropped-codemotionlogo-150x150.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/cropped-codemotionlogo-150x150.png","caption":"Codemotion"},"description":"Articles wirtten by the Codemotion staff. Tech news, inspiration, latest treends in software development and more.","sameAs":["https:\/\/x.com\/CodemotionIT"],"url":"https:\/\/www.codemotion.com\/magazine\/author\/codemotion-2\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A-600x400.png","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A-600x401.png","author_info":{"display_name":"Codemotion","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/codemotion-2\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png",816,401,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A-150x150.png",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A-300x147.png",300,147,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A-768x377.png",768,377,true],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png",816,401,false],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png",816,401,false],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png",816,401,false],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png",100,49,false],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A-180x128.png",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A.png",816,401,false],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A-400x225.png",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A-600x400.png",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/04\/1_jJv-QPlVbKu0kkRrD5gM9A-600x401.png",600,401,true]},"uagb_author_info":{"display_name":"Codemotion","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/codemotion-2\/"},"uagb_comment_info":0,"uagb_excerpt":"This article written by Todd Sharp, Cloud Developer Advocate at Oracle, was originally published on Oracle Developers Portal. Microservices are undoubtedly popular. There have been plenty of great posts on this blog that explain the advantages of using a microservice approach to building applications (or \u201cwhy you should use them\u201d). And the reasons are plentiful:&#8230;&hellip;","lang":"en","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/178","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/64"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=178"}],"version-history":[{"count":3,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/178\/revisions"}],"predecessor-version":[{"id":3113,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/178\/revisions\/3113"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/179"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=178"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=178"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=178"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=178"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}