Bagaimana membangun, menyebarkan dan menskalakan layanan web Java pada AWS – Part 1/4

Layanan Web Java di AWS tentunya salah satu hal yang perlu dipelajari, karena belum tentu semua bisa melakukannya. Di Nordic School of Technology, Anda akan mendapatkan pelajaran mengenai pemrogramam dan bersertifikat. Nordic merupakan salah satu kursus komputer di Bekasi yang menawarkan modul kursus komputer dengan metode Eropa. Belajar komputer dan pemrograman akan terasa mudah dan menyenangkan.

Kemudian untuk seri 4 bagian ini adalah panduan bagaimana cara membuat, menyebarkan, dan menskalakan layanan web Java RESTful menggunakan Spring, Docker dan AWS. Kami akan melihat tiga teknologi utama yang kami ajarkan dalam Java Web Course di Nordic School of Technology (Sekolah IT Nordic).

  1. Java & Spring – Spring Framework menyediakan model pemrograman dan konfigurasi yang komprehensif untuk aplikasi perusahaan berbasis Java modern.
  2. Docker – platform untuk membuat, mengirimkan, dan menjalankan aplikasi terdistribusi (layanan web RESTful pada kasus kami).
  3. Amazon Web Service (AWS) – AWS menawarkan layanan komputasi cloud yang handal, dapat diskalakan, dan terjangkau. Terdapat lebih dari 1000 layanan yang berbeda, yang paling sering digunakan adalah EC2 (mesin virtual) dan S3 (penyimpanan file), tetapi terdapat lebih banyak lagi jenis-jenisnya.

Tujuan

Diakhir seri ini Anda akan tahu cara bagaimana caranya menuliskan layanan Java Spring RESTful web. Anda juga akan belajar tentang apa itu Docker dan cara memaketkan aplikasi tersebut serta menyebarkannya di AW. Dalam dua bagian terakhir, kami akan membahas AWS dan bagaimana cara mengukur layanan web Anda di cloud tanpa mengkhawatirkan infrastruktur yang mendasarnya.

Diagram ini mengilustrasikan apa yang akan kita bangun dalam 4 artikel pembahasan berikutnya. Kode Java yang kami tuliskan di Bagian 1 akan dijalankan sebagai kontainer buruh pelabuhan pada EC2 instance AWS.

LEGEND

CLIENT – any web service consumer.

AWS – Amazon cloud ecosystem.

 VPC – Virtual Private Cloud is your private dedicated environment on AWS.

 ELB – Elastic Load Balancer balances requests to different servers based on traffic load or ther set criterias.

 ASG – Auto Scaling Group allows AWS to automatically launch new EC2 instances from templates (called AMIs).

 EC2 – AWS Virtual Machine service. Server where your code will run.

Security Group – security configuration

Region – Region where your servers are available.

Diagram 1: Deployment architecture

Overview 4 bagian

  1. Dibagian pertama, bagian awal, kita akan belajar tentang Java dan Spring dengan membangun aplikasi dan menjalankannya secara lokal
  2. Selanjutnya ibagian kedua, kita akan membahas Docker dan bagaimana megkontaineran aplikasi tersebut untuk disebarkan.
  3. Bagian ketiga berisikan seluruhnya tentang AWS dan bagaimana menggunakan layanan yang tersedia untuk menyebarkan aplikasi di cloud. Selain itu, kami juga akan mempelajari VPC dan Grup Keamanan juga.
  4. Dibagian terakhir, kami akan terus melanjutkan dengan AWS dan melihat ke fitur penskalaan otomatisnya. Singkatnya layanan ini memungkinkan Anda untuk mengatur penskalaan otomatis untuk server Anda yang akan secara otomatis akan melakukan penskalaan keluar ketika konsumsi layanan web Anda meningkat dan penskalaan kedalam, ketika klien lebih sedikit, rendah, atau menurun.

Bagian 1 – Membuat Aplikasi

Untuk membangun atau membuat aplikasinya, kita akan menggunakan hal-hal berikut stack:

  • Java 8
  • Spring Boot – membuatny menjadi lebih dalam membuat Aplikasi Spring berbasis produksi yang berdiri sendiri.
  • Maven 3 – Maven disini digunakan untuk mengelola semua ketergantungan
  • Apache Tomcat – Termasuk didalamnya proyek Spring dan akan digunakan untuk menjalankan server java.
  • IntelliJ IDEA – Pilihan IDE yang disarankan.

Tujuan

Kami ingin membangun sebuah layanan web RESTful yang akan menanggapi panggilan HTTP yang dibuat oleh klien dengan respons JSON. Pada tahap ini kami hanya ingin menjalankannya secara lokal sehingga, untuk saat ini tidak perlu khawatir untuk penerapan apa pun.

Layanan Anda akan menerima permintaan panggilan HTTP GET di:

http://localhost:8090/nordic/courses

dan respon dengan daftar semua kursus Nordik dalam bentuk JSON respon. Sebagai contoh:

{
 "code": 200,
 "message": "success",
 "courses":[{
    "id": 1001,
    "name": "Fundamentals",
    "description": "Python course for beginners",
    "price": 2370000.00,
    "level": "easy",
    "url": "nordic.id/fundamentals"
 }]
}

Anda juga dapat menyesuaikan respons yang Anda inginkan dengan cara menentukan kata kunci pencarian dengan parameter pencarian (searc) opsional dalam string kueri. Metode ini digunakan untuk mencari semua deskripsi kursus kami dan hanya memunculkan mata kuliah yang mengandung kata kunci tersebut.

Permintaan/panggilan seperti ini:

http://localhost:8090/nordic/courses?search=web

akan menghasilkan:

{
 "code": 200,
 "message": "success",
 "courses":[{
    "id": 1004,
    "name": "Java Web",
    "description": "Web services course in Java, Spring and AWS ",
    "price": 2370000.00,
    "level": "advanced",
    "url": "nordic.id/javaweb"
 }]
}

 

Bagaimana

Untuk menghindari terjadinya kesalahan pembangunan proyek, dari awal kita bisa menggunakan Spring Initializer untuk mengunduh template proyek yang dapat kita gunakan untuk membangun proyek tersebut. Untuk mengetahuinya, bisa dilihat terlebih dahulu Spring Initializer dan tentukan semua dependensi yang mungkin Anda perlukan (jangan khawatir, Anda selalu dapat menambahkan lebih banyak lagi nanti). Sebagai permulaan, karena kami sedang membangun layanan web, maka tentukanklah ketergantungan ‘web’ yang mencakup Apache Tomcat, Spring MVC, dan paket terkait lainnya.

Isikan kolom Grup dan Artefak (alur masing-masing proyek dan nama proyek tersebut) kemudian tekan Buat Proyek.

 

Setelah mengunduh proyek, jalankan proyek menggunakan IntelliJ IDEA.

Jika Anda tidak melihat pohon proyeknya di IDE.

Temukan Struktur Proyek (File – Struktur Proyek) dan pilih Modul.

Tambahkan baru dengan mengklik tombol ‘+’, pilih ‘Impor Modul’ dan arahkan ke proyek dalam struktur file. Tekan OK dan abaikan pesan eror jika ada yang muncul.

Sekarang seharusnya Anda melihat struktur proyek ini  dibagian kiri pohon.

Templet Proyek

Sebelum kita melanjutkan dengan menuliskan kode kita sendiri, mari kita lihat file-file template yang sudah disediakan oleh Spring Initializer untuk kita.

pom.xml – file ini terkait dengan Maven dan memastikan alur dependensi proyek kita Disini Anda dapat melihat bahwa Spring Initializer sudah menambahkan starter-web dan beberapa paket json. Setelah membangun atau membuat kode, paket yang ditentukan dalam file pom.xml diunduh dari Internet dan digunakan oleh program dalam lingkungan yang disebarkan.

[Artifact]Application.java – file ini dinamai setelah nama proyek yang Anda ditentukan. Dalam kasus kami, hal ini disebut CoursesApplication.java. File ini memungkinkan kita untuk mengeksekusi program menggunakan file JAR tunggal. Kami akan kembalai mebahas ini lagi nanti.

Meskipun dimungkinkan untuk mengemas layanan ini sebagai file WAR tradisional untuk kemudian ditempatkan ke server aplikasi eksternal, pendekatan yang lebih sederhana yang ditunjukkan di bawah ini membuat aplikasi ini bisa berdiri sendiri. Anda mengemas semuanya dalam satu file JAR yang dapat dieksekusi, didorong oleh metode baik Java utama yang sudah sekia lama. Sepanjang perjalan, Anda akan menggunakan dukungan Spring untuk menanamkan kontainer servlet Tomcat sebagai runtime HTTP, alih-alih menerapkannya ke bagian eksternal. “- https://spring.io/guides/gs/rest-service/

Inilah kira-kira apa yang akan Anda dapatkan dengan Spring Initializer. Sisanya tergantung kita, jadi mulailah mari kita menulis. 

Program Custom

Pertama mari buat file model yang menurut kita mungkin kana kita perlukan. File model adalah kelas java yang mewakili objek yang mungkin diperlukan program kita. Kita dapat menggunakan contoh respon untuk memahami domain dan apa saja persyaratan model kita tersebut.

{
 "code": 200,
 "message": "success",
 "courses":[{
   "id": 1001,
   "name": "Fundamentals",
   "description": "Python course for beginners",
   "price": 2370000.00,
   "level": "easy",
   "url": "nordic.id/fundamentals"
 }]
}

Disini kita melihat bahwa respon objek berisi variabel-variabel berikut:

Nama Variabel Nama Objek/Tipe Komentar
Response The entire response object containing the ‘code’, ‘message’ and ‘courses’.
Response.code Integer HTTP response codes
Response.message String “success” or the cause of error.
Response.courses Array Contains the relevant courses.
Course Single course
Course.id Integer Unique identifier of course.
Course.name String Name of the course
Course.description String Description of the course
Course.price Float Price of the course in IDR currency
Course.level String Difficulty level of the course Possible values: [easy, medium, advanced, challenge]
Course.uri String The website or other online resources of the course

Dari tabel di atas kita dapat melihat bahwa kita benar-benar hanya membutuhkan 2 objek model dalam proyek kita in: 1) Respons – memegang Kursus serta beberapa Metadata 2) Kursus – menyimpan informasi tentang suatu kursus.

Mari buat kelas Java yang mewakili objek-objek ini.

Membuat sumber daya yang merepresentasikan kelas

1) Respon Kelas

package com.nordic.demo.courses.model;

public class Response {
 public final Integer code;
 public final String message;
 @JsonInclude(Include.NON_NULL) // this tells Spring to ignore if value is null
 public final Courses[] courses;
 
 public Response(Integer code, String message, Courses[] courses) {
    this.code = code;
    this.message = message;
    this.courses = courses;
 }
}

2) Kursus Kelas

package com.nordic.demo.courses.model;

public class Course {
  public final Integer id;
  public final String name;
  public final String description;
  public final Float price;
  public final String level;
  public final String url;
 
  public Course(Integer id, String name, String desc, Float price, String level, String url) {
    this.id = id;
    this.name = name;
    this.description = desc;
    this.price = price;
    this.level = level;
    this.url = url;
  }
}

Idealnya kita harus mengulangi objek Kursus dan menerapkan Pola Builder disini. Ini adalah pola yang baik untuk digunakan ketika Anda memiliki objek dengan lebih dari 3 variabel dan termasuk didalamnya diperlukan juga variabel opsional. Karena keterbatasan lingkup artikel kita ini, maka kita tidak akan melakukannya sekarang.

Kelas-kelas ini digunakan untuk membuat struktur data yang tidak berubah. Immutable berarti bahwa semua variabel objek adalah final (sekali didefinisikan, mereka tidak akan pernah berubah) dan struktur data berarti objek hanya memegang data dan tidak memiliki perilaku (metode).

 

Membuat kelas pengontrol sumber daya

 Untuk menyajikan objek-objek ini ke klien kita perlu membuat kelas yang tahu bagimana cara mengontrol sumber daya. Kelas ini adalah kelas pengontrol sumber daya dan akan dipanggil dengan tepat.

Idealnya kita harus mengulangi objek Kursus dan menerapkan Pola Builder disini. Ini adalah pola yang baik untuk digunakan ketika Anda memiliki objek dengan lebih dari 3 variabel dan termasuk didalamnya diperlukan juga variabel opsional. Karena keterbatasan lingkup artikel kita ini, maka kita tidak akan melakukannya sekarang.

Kelas-kelas ini digunakan untuk membuat struktur data yang tidak berubah. Immutable berarti bahwa semua variabel objek adalah final (sekali didefinisikan, mereka tidak akan pernah berubah) dan struktur data berarti objek hanya memegang data dan tidak memiliki perilaku (metode).

 

Membuat kelas pengontrol sumber daya

 Untuk menyajikan objek-objek ini ke klien kita perlu membuat kelas yang tahu bagimana cara mengontrol sumber daya. Kelas ini adalah kelas pengontrol sumber daya dan akan dipanggil dengan tepat.

1) Kelas Kursus Pengontrol

package com.nordic.demo.courses.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CoursesController {

 @RequestMapping("/courses")
 public Greeting getCourses(@RequestParam(value="search") String findMeInDesc){

   try{
      Courses[] courses;
      CoursesRepositoryImpl coursesRepo = new CoursesRepositoryImpl() 
 
      if(findMeInDesc == null || findMeInDesc == "") 
         courses = coursesRepo.getAllCourses(); 
      else 
         courses = coursesRepo.findCoursesByKeywordInDesc(findMeInDesc); 
      return new Response(200, "success", courses);

   }catch(Exception e){ 
      return new Response(501, e.getMessage(), null); 
   }
 }
}
 

Pengontrol ini terlihat sederhana dan memang benar, tetapi banyak yang sesungguhnya terjadi didalamnya. Mari kita lihat langkah demi langkah.

Anotasi @RestController adalah anotasi baru di Spring 4. Ini menandai kelas tersebut sebagai pengontrol dimana setiap metode akan mengembalikan sebuah objek domain (model), bukan tampilan (misalnya dokumen html).

Anotasi @RequestMapping memastikan bahwa permintaan HTTP ke / kursus dipetakan dengan metode getCourses ().

“Contoh di atas tidak menentukan GET vs. PUT, POST, dan sebagainya, karena @RequestMapping memetakan semua operasi HTTP secara default. Gunakan @RequestMapping (metode = GET) untuk mempersempit pemetaan ini.“ –  https://spring.io/guides/gs/rest-service/

 @RequestParam mengikat nilai parameter string pencarian kueri ke dalam parameter findMeInDesc metode getCourses ().

Implementasi metode ini menciptakan dan kemudian mengembalikan objek Respons baru dengan kode, pesan dan atribut kursus berdasarkan apa yang dikembalikan oleh CoursesRepository.

Untuk mendapatkan kursus tersebut, baik semua atau dengan kata kunci, kami akan menggunakan bantuan dari pola repositori. KursusRepositori adalah objek yang menerapkan pola bernama. Untuk saat ini kami tidak akan menampilkan semua rincian implementasi dari repositori tetapi idenya adalah, bahwa di balik objek ini mungkin ada database, atau file statis dari beberapa macam. Untuk konsumen dari repositorihal tersebut tidak terlalu penting. Yang perlu kita ketahui sekarang, adalah bahwa repositori akan menangani operasi CRUD (buat, baca, perbarui, hapus) yang mungkin ingin digunakan klien. KursusRepositori kemudian, mengembalikan kami baik semua program atau kursus khusus yang ditemukan menggunakan kata kunci. Saat ini kita perlu mempercayai bahwa KursusRepository yang ditulis oleh orang lain tersebut akan mampu memberikan kita program yang benar dari database.

Sebelum metode dapat mengembalikan respons ke klien, objek Respons harus dikonversi ke JSON. Biasanya orang-orang akan melakukan ini menggunakan bantuan pustaka Gson atau Jackson dan secara manual mengonversi objek ke JSON sebelum mengembalikan data JSON tersebut. Berkat dukungan konverter pesan HTTP Spring, Anda tidak perlu lagi melakukan konversi ini secara manual dan karena Jackson 2 ada di classpath (alur kelas), Spring’s MappingJackson2HttpMessageConverter secara otomatis dipilih untuk mengonversi Respons instansi ke JSON.

Membuat Kursus Kelas Repositori/Penyimpanan

Untuk membuat kursus repositori program, kita akan menggunakan sesuatu yang disebut interface/antarmuka. Antarmuka dalam bahasa pemrograman Java adalah jenis abstrak yang digunakan untuk menentukan perilaku yang harus diimplementasikan oleh kelas tetapi tidak menerapkannya pada diri sendiri. Alih-alih detail penerapan metode ditentukan di kelas yang mengimplementasikan antarmukanya. Untuk mencapai pola ini kita perlu membuat 2 kelas lagi yaitu: 1) antarmuka itu sendiri dan 2) kelas yang mengimplementasikan antarmuka.

1) Kursus Repositori

interface CoursesRepository{
 public Course[] getAllCourses()
 public Course[] findCoursesByDescKeyword(keyword);
}

2) RepositoryImpl Kursus

public class CoursesRepositoryImpl implements CoursesRepository{
 
 public Course[] getAllCourses(){
   Course[] courses = new Course[dao]{
      new Course(1001, "Fundamentals", "3 month Python course for beginners", 2370000.00, "easy", "nordic.id/fundamentals"),
      new Course(1002, "Android", "3 month Android course for beginners", 2370000.00, "easy", "nordic.id/android"),
     new Course(1002, "Java", "3 month Java course for students who want to understand OOP", 2370000.00, "medium", "nordic.id/java"),
     new Course(1003, "Java Web", "3 month Java course for students who want to understand web services and cloud programming", 2370000.00, "advanced", "nordic.id/javaweb")
   };
   return courses;
 }

 public Course[] findCoursesByKeywordInDesc(keyword){
   return new Course[]{new Course(1001, keyword, keyword, 2370000.00, "easy", "nordic.id/"+keyword)};
 }

}

Seperti yang dapat Anda lihat dari atas, kami akan mengabaikan logika nyata untuk mendapatkan Kursus yang benar saat ini untuk kemudian mengembalikan objek tiruan sebagai gantinya. Jika kita akan menerapkan metode tersebut dengan fungsi yang nyata, saya akan menggunakan sesuatu yang disebut sebagai Objek Akses Database/Database Access Object (DAO) dan menyembunyikan komunikasi dengan database (misalnya SQL queries) di belakang kelas itu.

Diatas, Anda dapat melihat baris komentar yang mengacu pada penggunaan kelas DAO. Gagasan utamanya adalah bahwa ProgramRepositori harus menjaga operasi CRUD dari Kursus tetapi tidak perlu mengetahui apa pun terkait basis data. Alasannya adalah bahwa jika di masa depan kita ingin menukar database SQL misalnya dengan NoSQL, maka dengan demikian kode komunikasi database akan berubah, kita hanya memiliki satu kelas yang perlu kita perbarui. Pada akhirnya, perlu diingat bahwa program Anda mungkin akan tetap memerlukan akses ke basis suatu data di tempat lain selain hanya dari KursusRepositori dan jika kita tidak menggunakan DAO, kita perlu mengubah semua kelas yang menyertakan kode terkait basis data.

Membuat aplikasi bisa dieksekusi/dijalankan

Adalah mungkin untuk mengemas layanan ini sebagai file WAR tradisional. Seseorang akan kemudia menggunakan file WAR untuk ditempatkan ke server eksternal. Pendekatan yang lebih sederhana adalah membuat aplikasi yang berdiri sendiri. Anda mengemas semuanya dalam satu file JAR yang dapat dieksekusi, didorong oleh metode utama Java () yang sudah lama. Sebelumnya saya berjanji untuk mengunjungi kembali file CoursesApplication.java yang disertakan dengan proyek template, karena ini akan membantu kita untuk mewujudkannya. Mari lihat file-nya di sini.

package com.nordic.demo.courses;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CoursesApplication {
   public static void main(String[] args) {
     SpringApplication.run(CoursesApplication.class, args);
   }
}

Mari kita bedah kelas sederhana ini:

@SpringBootApplication adalah anotasi kenyamanan yang menambahkan semua hal berikut:

  • @Cinfiguration menandai kelas sebagai sumber definisi bean utama untuk konteks aplikasi.
  • @EnnableAutoConfiguration memberi tahu Spring Boot untuk mulai menambahkan berdasarkan pengaturan ruang kelas, bean lainnya, dan berbagai pengaturan properti.
  • Biasanya Anda akan menambahkan @EnableWebMvc untuk aplikasi Spring MVC, tetapi Spring Boot menambahkannya secara otomatis ketika melihat spring-webmvc di classpath/jalur kelas. Ini menandai aplikasi bekerja sebagai aplikasi web dan mengaktifkan perilaku utama seperti menyiapkan DispatcherServlet.
  • @ComponentScan memberi tahu Spring untuk mencari komponen, konfigurasi, dan layanan lain dalam paket halo, memungkinkannya menemukan pengontrol.

Metode utama () menggunakan metode SpringBoot’s SpringApplication.run () untuk meluncurkan aplikasi. Apakah Anda memperhatikan bahwa tidak ada satu baris XML? Tidak terdapat file web.xml juga. Aplikasi web ini adalah 100% Java murni dan Anda tidak harus berurusan dengan konfigurasi atau infrastruktur apa pun. – https://spring.io/guides/gs/rest-service/

Saat ini Anda tidak perlu benar-benar tahu apa itu beas, tetapi jika Anda tertarik disini terdapat penjelasan yang cukup baik.

Sekarang Anda tahu bahwa CoursesApplication.java akan membantu kita membangun file JAR yang dapat dieksekusi. Untuk benar-benar membangun file tersebut, kita dapat menggunakan perintah berikut sebagai terminal

$ mvn clean package

Perlu diingat bahwa untuk menggunakan perintah Maven Anda harus menginstal Maven3. Gunakan perintah ini untuk melakukannya

$ sudo apt-get install maven

Pastikan maven yang diinstal adalah versi 3 (tergantung pada paket Anda, mungkin saja paket Anda menginstal versi 2).

Menjalankan paket mvn clean akan membuat file JAR di folder ‘target’. Untuk menjalankan file JAR ini di lingkungan lokal Anda, jalankan perintah berikut: ’

$ java -jar target/courses-0.0.1-SNAPSHOT.jar

“The JAR name may vary depending on your project name, structure and configuration files. Nama JAR dapat bervariasi tergantung pada nama proyek Anda, struktur dan file konfigurasi”.

Mencoba Layanan

Layanan web RESTful Anda seharusnya sudah berjalan di port yang ditentukan. Untuk menentukan port layanan mana yang harus dijalankan, tambahkan baris berikut ke target.classess -> application.properties file:

server.port = 8090

Uji cobakan layanan dengan permintaan berikut:

http://localhost:8090/nordic/courses

http://localhost:8090/nordic/courses?search=web

Anda harus melihat Program dummy yang ditentukan dalam CoursesRepositoryImpl.java sebagai respons terhadap permintaan.

Jika Anda berhasil sejauh ini, Anda telah berhasil membangun aplikasi. Di Bagian 2 kita akan melihat kontainer dengan Docker dan bagaimana kita dapat membuat gambar yang mudah disebarkan dari JAR eksekusi yang baru saja kita buat. Gambar itu akan berisi kode program, dependensi, dan detail lingkungan lain yang dibutuhkan dalam satu file yang dapat dibagikan. File yang dapat digunakan untuk server apa pun yang Anda inginkan hanya dengan beberapa perintah. Yang lebih penting, dengan docker file gambar ini, Anda dapat mengotomatiskan penerapan sepenuhnya. Baca bagian 2 di sini.

Mendaftar untuk Nordic kursus