Pada artikel sebelumnya telah membahas mengenai angular js. Yups angular js adalah salah satu framework yang dikembangkan oleh google. Akan tetapi sejak angular versi 2, google hanya memberikan nama dengan angular, sedangkan untuk versi 1 mereka menamakan nya dengan angular js. Jika Anda menggunakan angular js maka kita menggunakan bahasa pemrograman javascript, sedangkan jika kita menggunakan angular 2 atau 4 maka nantinya kita akan menggunakan typescript.
Apa Itu TypeScrypt ?
TypeScrypt adalah bahasa pemrograman yang dikembangkan oleh microsoft, dimana TypeScrypt memiliki fitur strong-typing sehingga membuat developer lebih rapi dalam melakukan development sebuah aplikasi.
Jika Anda adalah seorang developer java, maka tidak perlu memiliki waktu lama untuk menguasai TypeScrypt. Sintak yang digunakan juga tidak jauh berbeda dengan javascript. Salah satu yang penulis sukai adalah terdapat autocomplete yang bisa kita gunakan jika kita menggunakan editor visual studio code untuk melakukan development dengan TypeScrypt.
Setup Project Angular 4
Pada artikel ini, penulis akan membuatkan sebuah artikel mengenai bagaimana setup project angular 4. Bagi Anda yang belum melakukan instalasi node js, silahkan lihat artikel nya di Instalasi Perlengkapan Coding Node JS. Untuk membuat project angular 4, kita dapat menggunakan bantuan angular cli. Untuk melakukan instalasi angular 4, silahkan jalankan perintah berikut.
npm install-g @angular/cli
Jika telah selesai, tahap selanjutnya kita akan membuat sebuah project angular 4 dengan perintah berikut.
ng new Belajar-Angular4
Jika berhasil maka project nya akan memiliki struktur folder seperti berikut.
Untuk menjalankan projectnya, silahkan jalankan perintah berikut.
ng serve
Nantinya akan dilakukan compile dan dilakukan transpiler dari TypeScrypt ke javascript versi ES5. Jika telah selesai, silahkan akses url http://localhost:4200 di browser Anda.
Membuat Hello Word Dengan Angular 4
Silahkan buka folder app yang terdapat di dalam folder src. Silahkan buka file app.component.html lalu ubah menjadi seperti berikut.
<!--The content below is only a placeholder and can be replaced.--><divstyle="text-align:center"><h1>
Welcome to {{title}}!!
</h1><imgwidth="300"src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo="></div><input[(ngModel)]="nama"/><h1>Hello {{nama}}</h1>
dari codingan diatas, dapat dilihat bahwa kita menggunakan directive ngModel dimana nantinya isi dari property nama akan dibinding ke <h1>Hello {{nama}}</h1> .
Jika langsung dijalankan maka akan muncul error, error disini disebabkan kita belum melakukan import untuk module FormsModule, untuk melakukan module tersebut, silahkan buka file app.module.ts lalu ubah codingan nya menjadi seperti berikut.
Setelah selesai, silahkan akses kembali http://localhost:4200 di browser anda, disana terdapat 1 inputan, silahkan isikan nama anda, jika berhasil maka akan muncul output seperti berikut.
Sekian artikel mengenai Setup Project Angular 4 dan Terima kasih :)
Secret Storage adalah suatu storage yang berfungsi untuk menyimpan data - data secret / rahasia misalnya seperti password, API Key, client id, client secret dan lain - lain.
Sebagai seorang developer, terutama backend developer, mereka biasanya akan membuat sebuah environment. Environment ini biasanya digunakan untuk menyimpan data - data penting misalnya seperti IP database, nama database, username dan juga password dari database. Secara tidak langsung, membuat environment seperti hal diatas sebenarnya merupakan hal yang mengerikan jika suatu waktu server yang kita gunakan dapat dibobol oleh pihak yang tidak berkepentingan sehingga file environment tersebut dapat dibaca. Bahaya lagi jika pihak tersebut dapat mengakses database dan mengunci data - data nya sehingga kita diharuskan membayar kepada mereka agar datanya dapat dikembalikan.
Untuk mengatasi hal diatas, kita harus menggunakan suatu database, dimana pada database tersebut kita dapat menyimpan nilai - nilai secret tersebut secara aman. Pada artikel ini, penulis akan membahas salah satu secret storage yang banyak digunakan dikalangan developer yaitu Vault.
Apa Itu Vault ?
Vault adalah tool untuk management secret suatu nilai yang dikembangkan oleh HashiCorp.
Biasanya vault akan digunakan untuk menyimpan data - data yang bersifat secret / rahasia misalnya seperti username, password, nama database dan IP dari suatu database. Vault memiliki banyak kelebihan diantaranya adalah Semua data yang disimpan ke dalam vault bersifat encrypted sehingga tidak dapat dibaca dan untuk dapat mengakses suatu data dari vault wajib menggunakan token.
Instalasi Vault
Untuk melakukan instalasi vault, silahkan download vault disini. Setelah download maka anda akan mendapatkan sebuah file, karena penulis menggunakan OSX maka nama file nya adalah vault_0.7.3_darwin_amd64.zip. Silahkan extract disuatu folder, lalu agar vault terbaca di terminal maka kita harus melakukan export path pada bash atau zsh. Silahkan jalankan perintah berikut untuk membuka file .zshrc.
vim ~/.zshrc
Jika menggunakan bash maka anda dapat menggunakan perintah.
vim ~/.bash_profile
Kemudian masukkan codingan berikut pada baris yang paling atas.
Pada codingan diatas, kita melakukan export path untuk vault, silahkan sesuaikan path vault anda. Pada baris kedua, penulis mendeklarasikan VAULT_ADDR, biasanya konfigurasi ini digunakan untuk vault client yang akan berkomunikasi dengan vault server. Langkah selanjutnya, silahkan update .zshrc dengan perintah.
source .zshrc
atau jika anda menggunakan bash :
source .bash_profile
Lalu selanjutnya jalankan server vault, karena sekarang masih tahap development, maka cara menjalankan seperti berikut.
vault server -dev
Lalu untuk mengecek apakah server vault telah jalan atau tidak, silahkan jalankan perintah berikut.
vault status
Jika berhasil maka akan muncul output seperti berikut.
Silahkan buka terminal anda, lalu jalankan perintah berikut.
vault write secret/belajar value=rizkimufrizal
Pada contoh diatas, kita menulis sebuah nilai yaitu rizkimufrizal, dimana nilai tersebut ditulis pada path/key secret/belajar. Jika anda memiliki banyak nilai, lebih baik anda menggunakan file json yang dapat diimport ke vault, silahkan buat file json dengan nama file vault.json, lalu masukkan codingan seperti berikut.
Pada codingan json diatas, dapat kita lihat bahwa kita membuat banyak object, diantaranya ada object spring, datasource dan lain - lain, dimana pada codingan diatas kita menyimpan data - data url, username dan password. Untuk melakukan import ke vault, silahkan jalankan perintah berikut.
vault write secret/belajar @vault.json
Untuk membaca nilai dari diatas, silahkan jalankan perintah berikut.
vault read secret/belajar
Maka hasilnya akan seperti berikut.
Key Value
--------
refresh_interval 768h0m0s
spring map[datasource:map[password:admin url:jdbc:mariadb://127.0.0.1:3306/microservice_book?autoReconnect=true username:root]]
Agar mempermudah membaca value nya, silahkan jalankan perintah berikut untuk menghasilkan output json.
Untuk mengakses value tersebut, kita bisa menggunakan fungsi token yang disediakan oleh vault, silahkan jalankan perintah berikut untuk membuat sebuah token.
vault token-create
Jika berhasil maka akan muncul output seperti berikut.
Biasanya token yang digunakan adalah 09cb9604-f9df-c3bc-6e0c-dc1d3bd3a1fc. Setiap bahasa pemrograman memiliki library tersendiri untuk dapat mengakses vault, silahkan lihat list library tersebut disini.
Implementasi Akses Vault Dengan Spring Framework
Pada artikel ini, penulis akan melakukan implementasi dengan menggunakan Spring Vault. Silahkan buat sebuah project spring boot melalui Spring Initializr, Silahkan isikan property menjadi seperti berikut.
Silahkan download dan import ke IDE anda. Lalu ubah codingan pada file build.gradle menjadi seperti berikut.
Selanjutnya silahkan buat sebuah package configuration lalu buat sebuah class kotlin didalam nya dengan nama VaultConfiguration lalu masukkan codingan seperti berikut.
packageorg.rizki.mufrizal.belajar.spring.vault.configurationimportorg.springframework.context.annotation.Configurationimportorg.springframework.context.annotation.PropertySourceimportorg.springframework.vault.authentication.ClientAuthenticationimportorg.springframework.vault.authentication.TokenAuthenticationimportorg.springframework.vault.client.VaultEndpointimportorg.springframework.vault.config.AbstractVaultConfigurationimportjava.net.URI/**
* Created by rizkimufrizal on 6/19/17.
*/@Configuration@PropertySource("classpath:application.properties")classVaultConfiguration:AbstractVaultConfiguration(){overridefunclientAuthentication():ClientAuthentication=TokenAuthentication(environment.getRequiredProperty("vault.token"))overridefunvaultEndpoint():VaultEndpoint=VaultEndpoint.from(URI(environment.getRequiredProperty("vault.url")))}
Codingan diatas berfungsi sebagai konfigurasi dari vault, dimana kita melakukan set token terlebih dahulu agar dapat nilai secret nya dapat diakses. Selanjutnya silahkan buka main class lalu masukkan codingan seperti berikut.
packageorg.rizki.mufrizal.belajar.spring.vaultimportorg.slf4j.LoggerFactoryimportorg.springframework.beans.factory.annotation.Autowiredimportorg.springframework.boot.CommandLineRunnerimportorg.springframework.boot.SpringApplicationimportorg.springframework.boot.autoconfigure.SpringBootApplicationimportorg.springframework.core.env.Environmentimportorg.springframework.vault.annotation.VaultPropertySource@SpringBootApplication@VaultPropertySource(value="secret/belajar")classBelajarSpringVaultApplication@Autowiredconstructor(valenvironment:Environment):CommandLineRunner{privatevallogger=LoggerFactory.getLogger(BelajarSpringVaultApplication::class.java)overridefunrun(varargargs:String?){logger.info("hasil secret dari url : ${environment.getRequiredProperty("spring.datasource.url")}")logger.info("hasil secret dari username : ${environment.getRequiredProperty("spring.datasource.username")}")logger.info("hasil secret dari password : ${environment.getRequiredProperty("spring.datasource.password")}")}}funmain(args:Array<String>){SpringApplication.run(BelajarSpringVaultApplication::class.java,*args)}
Berikut adalah penjelasan mengenai codingan diatas :
@VaultPropertySource berfungsi untuk mengambil secret berdasarkan path / key, tadi kita telah menyimpan sebuah nilai secret pada secret/belajar.
environment.getRequiredProperty("spring.datasource.url") berfungsi untuk mengambil nilai yang berasal dari key spring.datasource.url, jadi key yang diambil harus sesuai dengan key yang dibuat.
Oke, selanjutnya kita akan membuat sebuah test untuk memastikan bahwa environment yang dibaca adalah benar, silahkan buka file BelajarSpringVaultApplicationTests yang ada didalam package test, lalu ubah menjadi seperti berikut.
packageorg.rizki.mufrizal.belajar.spring.vaultimportcom.winterbe.expekt.shouldimportorg.junit.Testimportorg.junit.runner.RunWithimportorg.slf4j.LoggerFactoryimportorg.springframework.beans.factory.annotation.Autowiredimportorg.springframework.boot.test.context.SpringBootTestimportorg.springframework.core.env.Environmentimportorg.springframework.test.context.junit4.SpringRunnerimportorg.springframework.vault.annotation.VaultPropertySource@RunWith(SpringRunner::class)@SpringBootTest@VaultPropertySource(value="secret/belajar")classBelajarSpringVaultApplicationTests{@Autowiredlateinitvarenvironment:Environmentprivatevallogger=LoggerFactory.getLogger(BelajarSpringVaultApplicationTests::class.java)@TestfuntestUrl(){logger.info("begin test url")environment.getRequiredProperty("spring.datasource.url").should.equal("jdbc:mariadb://127.0.0.1:3306/microservice_book?autoReconnect=true")environment.getRequiredProperty("spring.datasource.url").should.not.`null`environment.getRequiredProperty("spring.datasource.url").should.not.`empty`logger.info("end test url")}@TestfuntestUsername(){logger.info("begin test username")environment.getRequiredProperty("spring.datasource.username").should.equal("root")environment.getRequiredProperty("spring.datasource.username").should.not.`null`environment.getRequiredProperty("spring.datasource.username").should.not.`empty`logger.info("end test username")}@TestfuntestPassword(){logger.info("begin test password")environment.getRequiredProperty("spring.datasource.password").should.equal("admin")environment.getRequiredProperty("spring.datasource.password").should.not.`null`environment.getRequiredProperty("spring.datasource.password").should.not.`empty`logger.info("end test password")}}
Jika menggunakan terminal, silahkan jalankan dengan perintah berikut.
gradle test
Jika menggunakan Intellij IDEA, klik kanan pada class test, lalu pilih run seperti berikut.
Dan berikut adalah hasil test nya.
Sekian artikel mengenai Belajar Secret Storage Dengan Vault dan Terima kasih :). Untuk source code lengkap, penulis publish di Belajar Secret Storage Dengan Vault.
Pada artikel sebelumnya, penulis telah membahas mengenai setup project kotlin dengan menggunakan gradle. Nah pada artikel ini, penulis akan membahas sedikit mengenai null safety pada kotlin.
Apa Itu Null Safety
Sebagai developer java, anda pasti sering menemui yang namanya NullPointerException atau disingkat dengan NPE. Terkadang kita akan mengecek seluruh object apakah terdapat potensi NPE atau tidak dan NPE ini sangat sering terjadi terutama jika anda adalah android developer. Pada kotlin, anda dapat membedakan antara variabel yang boleh null dan yang tidak boleh null. Supaya lebih memahami, silahkan buka project yang dulu pernah anda buat, lalu buatlah sebuah file kotlin di dalam package org.rizki.mufrizal.belajarKotlin dengan nama NullSafety. Kemudian isikan codingan seperti berikut.
packageorg.rizki.mufrizal.belajarKotlin/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafety{companionobject{@JvmStaticfunmain(args:Array<String>){varnama="rizki"nama=null//errorprint("hello $nama")}}}
Dari codingan diatas, maka secara otomatis codingan anda akan error seperti berikut.
Error ini disebabkan karena secara default variabel pada kotlin tidak boleh diisi dengan null, sehingga dengan error ini developer lebih dapat mengatasi NPE. Agar variabel diatas dapat diisi dengan null maka silahkan ubah codingan nya menjadi seperti berikut.
packageorg.rizki.mufrizal.belajarKotlin/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafety{companionobject{@JvmStaticfunmain(args:Array<String>){varnama:String?="rizki"nama=nullprint("hello $nama")}}}
Tanda dari ? berfungsi agar variabel tersebut dapat diisi dengan null. Oke langkah selanjutnya adalah ketika anda ingin mengetahui panjang dari suatu string, biasanya kita akan menggunakan function dari length, Jika anda menggunakan tanda ? maka setiap mengakses function length maka anda wajib juga menyertakan tanda ?, di IntelliJ IDEA, ketika anda mencoba mengakses function length tanpa tanda ? maka warna nya akan gelap pertanda bahwa anda diwajibkan menggunakan tanda ? seperti berikut.
Jika anda tidak menggunakan tanda ? maka akan compiler akan memberitahukan error karena variabel memiliki nilai null. Untuk mengatasi hal demikian, silahkan ubah codingan menjadi seperti berikut.
packageorg.rizki.mufrizal.belajarKotlin/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafety{companionobject{@JvmStaticfunmain(args:Array<String>){varnama:String?="rizki"nama=nullprint("hello $nama dengan panjang nama : ${nama?.length}")}}}
Untuk mempermudah melakukan test, silahkan ubah codingan diatas menjadi seperti berikut.
packageorg.rizki.mufrizal.belajarKotlin/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafety{funnullOrNot(text:String?)="hello $text dengan panjang text : ${text?.length}"companionobject{@JvmStaticfunmain(args:Array<String>){println(NullSafety().nullOrNot(text="rizki"))println(NullSafety().nullOrNot(text=null))}}}
Jika pada codingan sebelumnya kita langsung melakukan print, maka pada codingan ini kita mendeklarasikan sebuah function dengan mengembalikan type data string. Pada function nullOrNot terdapat 1 parameter yaitu text dimana parameter ini dapat diisi dengan null dikarenakan menggunakan tanda ?. Untuk mengembalikan data dalam bentuk string, kita dapat langsung melakukan return jika codingan hanya sebaris seperti codingan diatas dan tanpa perlu menggunakan keyword return.
Langkah selanjutnya, kita akan membuat test nya, silahkan buat sebuah kotlin file dengan nama NullSafetyTest di dalam package test, kemudian isikan codingan seperti berikut.
packageorg.rizki.mufrizal.belajarKotlinimportcom.winterbe.expekt.shouldimportorg.jetbrains.spek.api.Spekimportorg.jetbrains.spek.api.dsl.givenimportorg.jetbrains.spek.api.dsl.itimportorg.jetbrains.spek.api.dsl.on/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafetyTest:Spek({given("a class NullSafety"){valnullSafety=NullSafety()on("set text to not null"){valtextNotNull=nullSafety.nullOrNot(text="rizki")it("should return not null"){textNotNull.should.equal("hello rizki dengan panjang text : 5")}}on("set text to null"){valtextNull=nullSafety.nullOrNot(text=null)it("should return null"){textNull.should.equal("hello null dengan panjang text : null")}}}})
Memeriksa Null
Jika kita menggunakan tanda ? maka jika anda mengakses suatu function contohnya length maka kita akan mendapatkan output null, terkadang kita ingin mengambalikan value yang lain. Alaternatif lain adalah dengan menggunakan fungsi if. Silahkan edit source code yang ada pada class NullSafety seperti berikut.
packageorg.rizki.mufrizal.belajarKotlin/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafety{funnullOrNot(text:String?)="hello $text dengan panjang text : ${text?.length}"funnullOrNotIf(text:String?)=if(text!=null)"hello $text dengan panjang text : ${text.length}"else"Kosong / Isinya null"companionobject{@JvmStaticfunmain(args:Array<String>){println(NullSafety().nullOrNot(text="rizki"))println(NullSafety().nullOrNot(text=null))println(NullSafety().nullOrNotIf(text="mufrizal"))println(NullSafety().nullOrNotIf(text=null))}}}
Pada kodingan diatas kita ada penambahan 1 function yaitu nullOrNotIf dimana sebenarnya function ini juga sama dengan function nullOrNot, bedanya yaitu pada function ini kita melakukan pengecekan null terhadap variabel text sehingga pada saat kita mengakses function length dari variabel text, kita tidak perlu lagi menggunakan tanda ?. Jika kita memasukkan null, maka nantinya akan dicetak Kosong / Isinya null sedangkan jika tidak null maka akan dicetak kalimat hello mufrizal dengan panjang text : 8.
Selain menggunakan if else, untuk mengecek null, kita juga dapat menggunakan elvis, silahkan ubah codingan seperti berikut.
packageorg.rizki.mufrizal.belajarKotlin/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafety{funnullOrNot(text:String?)="hello $text dengan panjang text : ${text?.length}"funnullOrNotIf(text:String?)=if(text!=null)"hello $text dengan panjang text : ${text.length}"else"Kosong / Isinya null"funnullOrNotElvis(text:String?):String{vallength=text?.length?:0returnif(length!=0)"hello $text dengan panjang text : $length"else"Kosong / Isinya null"}companionobject{@JvmStaticfunmain(args:Array<String>){println(NullSafety().nullOrNot(text="rizki"))println(NullSafety().nullOrNot(text=null))println(NullSafety().nullOrNotIf(text="mufrizal"))println(NullSafety().nullOrNotIf(text=null))println(NullSafety().nullOrNotElvis(text="rizki mufrizal"))println(NullSafety().nullOrNotElvis(text=null))}}}
Dengan menggunakan elvis, kita hanya perlu menggunakan operator ?:, sintak ini mirip dengan ternary operator. Jika text?.length tidak null maka akan dikembalikan nilai text?.length, sedangkan jika null maka akan dikembalikan nilai 0.
Dan yang terakhir adalah adanya operator !!, biasanya operator ini berfungsi untuk mengembalikan data yang benar - benar tidak null, jika null maka akan menghasilkan error, berikut adalah contoh penggunaan !!, silahkan ubah source code seperti berikut.
packageorg.rizki.mufrizal.belajarKotlin/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafety{funnullOrNot(text:String?)="hello $text dengan panjang text : ${text?.length}"funnullOrNotIf(text:String?)=if(text!=null)"hello $text dengan panjang text : ${text.length}"else"Kosong / Isinya null"funnullOrNotElvis(text:String?):String{vallength=text?.length?:0returnif(length!=0)"hello $text dengan panjang text : $length"else"Kosong / Isinya null"}funnullOrNotNew(text:String?)="hello $text dengan panjang text : ${text!!.length}"companionobject{@JvmStaticfunmain(args:Array<String>){println(NullSafety().nullOrNot(text="rizki"))println(NullSafety().nullOrNot(text=null))println(NullSafety().nullOrNotIf(text="mufrizal"))println(NullSafety().nullOrNotIf(text=null))println(NullSafety().nullOrNotElvis(text="rizki mufrizal"))println(NullSafety().nullOrNotElvis(text=null))println(NullSafety().nullOrNotNew(text="mufrizal rizki"))}}}
oke langkah selanjutnya kita akan membuat test nya, silahkan ubah source code yang ada di dalam file NullSafetyTest seperti berikut.
packageorg.rizki.mufrizal.belajarKotlinimportcom.winterbe.expekt.shouldimportorg.jetbrains.spek.api.Spekimportorg.jetbrains.spek.api.dsl.givenimportorg.jetbrains.spek.api.dsl.itimportorg.jetbrains.spek.api.dsl.on/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafetyTest:Spek({given("a class NullSafety"){valnullSafety=NullSafety()on("set text to not null"){valtextNotNull=nullSafety.nullOrNot(text="rizki")it("should return not null"){textNotNull.should.equal("hello rizki dengan panjang text : 5")}}on("set text to null"){valtextNull=nullSafety.nullOrNot(text=null)it("should return null"){textNull.should.equal("hello null dengan panjang text : null")}}on("set text to not null if"){valtextNull=nullSafety.nullOrNotIf(text="mufrizal")it("should return null"){textNull.should.equal("hello mufrizal dengan panjang text : 8")}}on("set text to null if"){valtextNull=nullSafety.nullOrNotIf(text=null)it("should return null"){textNull.should.equal("Kosong / Isinya null")}}on("set text to not null elvis"){valtextNull=nullSafety.nullOrNotElvis(text="rizki mufrizal")it("should return null"){textNull.should.equal("hello rizki mufrizal dengan panjang text : 14")}}on("set text to null elvis"){valtextNull=nullSafety.nullOrNotElvis(text=null)it("should return null"){textNull.should.equal("Kosong / Isinya null")}}on("set text to not null !!"){valtextNull=nullSafety.nullOrNotNew(text="mufrizal rizki")it("should return null"){textNull.should.equal("hello mufrizal rizki dengan panjang text : 14")}}}})
Memeriksa Null Pada Collections
Terkadang ketika memasukkan suatu nilai ke sebuah collection, nilai tersebut dapat berupa null. Jika menggunakan kotlin, terdapat function filterNotNull yang berfungsi untuk menghilangkan value null yang terdapat di dalam collection. Silahkan ubah codingan nya menjadi seperti berikut.
packageorg.rizki.mufrizal.belajarKotlin/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafety{funnullOrNot(text:String?)="hello $text dengan panjang text : ${text?.length}"funnullOrNotIf(text:String?)=if(text!=null)"hello $text dengan panjang text : ${text.length}"else"Kosong / Isinya null"funnullOrNotElvis(text:String?):String{vallength=text?.length?:0returnif(length!=0)"hello $text dengan panjang text : $length"else"Kosong / Isinya null"}funnullOrNotNew(text:String?)="hello $text dengan panjang text : ${text!!.length}"funfilterCollection(list:List<*>)=list.filterNotNull()companionobject{@JvmStaticfunmain(args:Array<String>){println(NullSafety().nullOrNot(text="rizki"))println(NullSafety().nullOrNot(text=null))println(NullSafety().nullOrNotIf(text="mufrizal"))println(NullSafety().nullOrNotIf(text=null))println(NullSafety().nullOrNotElvis(text="rizki mufrizal"))println(NullSafety().nullOrNotElvis(text=null))println(NullSafety().nullOrNotNew(text="mufrizal rizki"))vallist=mutableListOf<String?>()list.add("rizki")list.add("mufrizal")list.add(null)vallistNotNull=NullSafety().filterCollection(list)listNotNull.forEach{println("Nama Saya $it")}}}}
Pada codingan diatas terdapat tambahan yaitu tambahan function filterCollection, dimana didalam function tersebut dilakukan filter terhadap list dengan type data bebas, mengapa bebas ? ini dikarenakan kita menggunakan tanda * atau sama juga dengan generic. Untuk melakukan perulangan terhadap variabel listNotNull maka dapat menggunakan function forEach. Disini saya menggunakan variabel it, variabel it sebenarnya variabel yang mengembalikan nilai dari perulangan variabel listNotNull. Jadi variabel it tergantung dari type data yang ada di dalam list tersebut.
Tahap selanjutnya kita membuat test nya, silahkan ubah codingan NullSafetyTest seperti berikut.
packageorg.rizki.mufrizal.belajarKotlinimportcom.winterbe.expekt.shouldimportorg.jetbrains.spek.api.Spekimportorg.jetbrains.spek.api.dsl.givenimportorg.jetbrains.spek.api.dsl.itimportorg.jetbrains.spek.api.dsl.on/**
* Created by rizkimufrizal on 6/12/17.
*/classNullSafetyTest:Spek({given("a class NullSafety"){valnullSafety=NullSafety()on("set text to not null"){valtextNotNull=nullSafety.nullOrNot(text="rizki")it("should return not null"){textNotNull.should.equal("hello rizki dengan panjang text : 5")}}on("set text to null"){valtextNull=nullSafety.nullOrNot(text=null)it("should return null"){textNull.should.equal("hello null dengan panjang text : null")}}on("set text to not null if"){valtextNull=nullSafety.nullOrNotIf(text="mufrizal")it("should return null"){textNull.should.equal("hello mufrizal dengan panjang text : 8")}}on("set text to null if"){valtextNull=nullSafety.nullOrNotIf(text=null)it("should return null"){textNull.should.equal("Kosong / Isinya null")}}on("set text to not null elvis"){valtextNull=nullSafety.nullOrNotElvis(text="rizki mufrizal")it("should return null"){textNull.should.equal("hello rizki mufrizal dengan panjang text : 14")}}on("set text to null elvis"){valtextNull=nullSafety.nullOrNotElvis(text=null)it("should return null"){textNull.should.equal("Kosong / Isinya null")}}on("set text to not null !!"){valtextNull=nullSafety.nullOrNotNew(text="mufrizal rizki")it("should return null"){textNull.should.equal("hello mufrizal rizki dengan panjang text : 14")}}on("set collection filter"){vallist=mutableListOf<String?>()list.add("rizki")list.add("mufrizal")list.add(null)valcollectionNotNull=nullSafety.filterCollection(list)it("should return collection not null"){collectionNotNull.should.not.`null`collectionNotNull.should.any.elements("rizki","mufrizal")collectionNotNull.should.have.all.elements("rizki","mufrizal")collectionNotNull.should.have.size.equal(2)collectionNotNull.should.have.size.above(1)}}}})
Untuk melakukan test diatas, silahkan jalankan perintah berikut.
gradle test
dan berikut hasilnya.
:compileKotlin
Using kotlin incremental compilation
:compileJava NO-SOURCE
:copyMainKotlinClasses
:processResources NO-SOURCE
:classes UP-TO-DATE
:compileTestKotlin
Using kotlin incremental compilation
:compileTestJava NO-SOURCE
:copyTestKotlinClasses
:processTestResources NO-SOURCE
:testClasses UP-TO-DATE
:junitPlatformTest
Test run finished after 5131 ms
[ 14 containers found ][ 0 containers skipped ][ 14 containers started ][ 0 containers aborted ][ 14 containers successful ][ 0 containers failed ][ 9 tests found ][ 0 tests skipped ][ 9 tests started ][ 0 tests aborted ][ 9 tests successful ][ 0 tests failed ]
:test SKIPPED
BUILD SUCCESSFUL
Total time: 13.815 secs
Sekian artikel mengenai mengenal null safety pada kotlin, jika ada saran dan komentar silahkan isi dibawah dan terima kasih :)
Pada artikel instalasi perlengkapan coding kotlin, penulis telah membahas sedikit mengenai bagaimana cara instalasi kotlin dengan sdkman. Oke, pada artikel ini, penulis akan membahas mengenai dasar - dasar dari bahasa pemrograman kotlin. Project yang akan kita buat adalah berbasis gradle, jika anda pengguna linux dan windows silahkan ikutin tutorial langsung dari websitenya disini. Untuk penggunakan OSX, anda dapat melakukan instalasi dengan bantuan Homebrew seperti berikut.
brew install gradle
Seperti biasa, penulis menggunakan IDE IntelliJ IDEA, anda dapat menggunakan versi community maupun versi ultimate karena dua - dua nya telah mendukung bahasa pemrograman kotlin.
Silahkan buka IDE anda, lalu untuk membuat sebuah project silahkan pilih menu create new project, lalu pilih gradle dan cek list di bagian kotlin seperti gambar berikut.
Lalu pilih next, di bagian groupid silahkan isikan org.rizki.mufrizal.belajar.kotlin dan pada bagian artifact nya isikan dengan Belajar-Kotlin, lalu klik next hingga akan muncul project location, silahkan sesuaikan dengan folder project anda dan klik finish. Berikut adalah project yang berhasil digenerate oleh IntelliJ IDEA.
Secara default, project belum memiliki package untuk class - class kotlin, silahkan akses project anda dengan menggunakan terminal, lalu jalankan perintah berikut.
Silahkan lihat kembali project anda yang ada di IntelliJ IDEA, maka akan terbentuk 2 sub directory dari src yaitu main untuk source code nya, sedangkan test untuk keperluan testing. Langkah selanjutnya silahkan buka file build.gradle lalu ubah menjadi seperti berikut.
Pada konfigurasi diatas, terdapat beberapa tambahan yaitu penulis menambahkan library test untuk kotlin yang disupport langsung dari jetbrains yaitu spekframework. Untuk fungsi assert, penulis menggunakan framework expekt.
Silahkan buat sebuah class App di dalam package org.rizki.mufrizal.belajarKotlin, silahkan sesuaikan dengan package anda, lalu masukkan codingan seperti berikut.
packageorg.rizki.mufrizal.belajarKotlinimportjava.math.BigDecimal/**
* Created by rizkimufrizal on 6/3/17.
*/classApp{funextensionMoney(extension:String,money:BigDecimal):String{return"$extension $money"}companionobject{@JvmStaticfunmain(args:Array<String>){valmoney=App().extensionMoney(extension="Rp",money=BigDecimal(5000))println("saya mempunyai uang sebesar $money")}}}
Berikut adalah beberapa penjelasan dari codingan diatas :
fun berfungsi untuk mendeklarasikan sebuah function / method pada kotlin. Jika anda tidak mendeklarasikan sebuah type data maka secara default method tersebut adalah berupa Unit atau void.
"$extension $money" adalah contoh dari string interpolation, sehingga yang memiliki tanda $ akan dieksekusi.
companion object sebagai static jika anda menggunakan bahasa pemrograman java.
@JvmStatic juga sebagai static, akan tetapi berbeda dengan companion object, dimana companion object hanya dapat diakses melalui instance, sedangkan jika menggunakan @JvmStatic maka anda dapat langsung memanggil suatu fungsi dari class nya langsung. Contoh penggunaan ini akan dibahas pada artikel selanjutnya.
val berfungsi untuk mendeklarasikan variabel yang bersifat immutable / jika object nya telah dibuat maka isi dari vaeriabel tersebut tidak dapat dirubah, sedangkan var kebalikan dari val yaitu bersifat mutable.
money adalah variabel dengan type data string. Mengapa type string ? karena return dari function extensionMoney adalah string. Tanpa mendeklarasikan type data, kotlin dapat dengan mudah menebak type data yang ada di dalam variabel money.
Untuk menjalankan codingan diatas, silahkan klik pada icon kotlin dibagian kiri, lalu pilih menu run seperti berikut.
Oke, langkah selanjutnya kita akan melakukan test, silahkan buat sebuah file AppTest di dalam package test anda. Lalu masukkan codingan seperti berikut.
packageorg.rizki.mufrizal.belajarKotlinimportcom.winterbe.expekt.shouldimportorg.jetbrains.spek.api.Spekimportorg.jetbrains.spek.api.dsl.givenimportorg.jetbrains.spek.api.dsl.itimportorg.jetbrains.spek.api.dsl.onimportjava.math.BigDecimal/**
* Created by rizkimufrizal on 6/3/17.
*/classAppTest:Spek({given("a extension money"){valapp=App()on("set extension and money"){valmoney=BigDecimal(7000)valextensionMoney=app.extensionMoney("Rp",money)it("should return extension and money"){extensionMoney.should.equal("Rp $money")}}}})
Untuk menjalankan test diatas, silahkan akses project anda dengan terminal lalu jalankan perintah berikut.
gradle test
Jika berhasil maka akan muncul output seperti berikut.
:compileKotlin UP-TO-DATE
:compileJava NO-SOURCE
:copyMainKotlinClasses UP-TO-DATE
:processResources NO-SOURCE
:classes UP-TO-DATE
:compileTestKotlin
Using kotlin incremental compilation
:compileTestJava NO-SOURCE
:copyTestKotlinClasses UP-TO-DATE
:processTestResources NO-SOURCE
:testClasses UP-TO-DATE
:junitPlatformTest
Test run finished after 5066 ms
[ 4 containers found ][ 0 containers skipped ][ 4 containers started ][ 0 containers aborted ][ 4 containers successful ][ 0 containers failed ][ 1 tests found ][ 0 tests skipped ][ 1 tests started ][ 0 tests aborted ][ 1 tests successful ][ 0 tests failed ]
:test SKIPPED
BUILD SUCCESSFUL
Total time: 9.272 secs
Sekian artikel mengenai setup project kotlin, jika ada saran dan komentar silahkan isi dibawah dan terima kasih :)
API Gateway merupakan gerbang dari beberapa API, bertugas sebagai management API, merge beberapa API, authentication API dan lain - lain.
Berbicara mengenai API gateway maka tidak terlepas dengan pembahasan microservice. Microservice itu sendiri sebenarnya adalah kumpulan dari beberapa service atau kumpulan dari beberapa API. API ini biasanya berbentuk REST API menggunakan protokol http. Microservice sendiri sebenarnya berasal dari monolithic yang telah dipecah. Monolithic adalah aplikasi yang sehari - hari kita kembangkan, dimana semua module terdapat di dalam 1 aplikasi yang sangat besar.
Client biasanya hanya mengakses 1 URL REST API sedangkan microservice memiliki banyak service REST API, untuk mengatasi masalah ini maka kita gunakan API gateway. Terdapat banyak contoh API gateway yang ada di pasaran contohnya kong, tyk, API Umbrella dan lain - lain.
Bagaimana arsitektur yang pernah saya gunakan ?
Biasanya saya akan membuat microservice dengan stack spring framework :). Mengapa menggunakan spring framework ? ya alasan nya karena framework ini merupakan framework yang sudah memiliki banyak support, terutama dalam hal membuat REST API, authentication dengan OAuth2, session dan lain - lain. Berikut adalah arsitektur yang pernah saya gunakan untuk membuat microservice dan API gateway sederhana.
Dari gambar diatas dapat dilihat bahwa aplikasi yang dibuat sangatlah besar meskipun hanya membuat service buku dan review buku. Pada gambar diatas terdapat :
database redis : ini kita gunakan untuk menyimpan session
database authentication : database untuk menyimpan data user, client credenetial dan lain - lain
database book : database untuk menyimpan data - data katalog buku
database review : database untuk menyimpan data - data review dari sebuah buku
authorization server : adalah authorization server yang berfungsi sebagai management otorisasi setiap service REST API. Authorization yang saya gunakan adalah berbasis OAuth2, dimana antar service wajib melakukan authentication terlebih dahulu sebelum mengakses service yang lain, contohnya adalah ketika service book ingin mengakses service review maka service book diharuskan login terlebih dahulu dengan menggunakan authentication OAuth2 grant type client credentials. Tidak hanya antar service, API gateway yang akan mengakses suatu service juga wajib melakukan authentication terlebih dahulu, akan tetapi setiap service memiliki client id, client secret dan hak akses masing - masing sehingga memiliki keterbatasan dalam mengakses masing - masing service. Bagi anda yang masih bingung dengan OAuth2, silahkan baca artikel Belajar OAuth2.
service book : REST API penyedia book
service review : REST API penyedia review book
API Gateway : yang bertugas untuk management API. Biasanya saya akan melakukan merge beberapa request API jika client membutuhkan banyak API. Contohnya jika kita membutuhkan API yang berisi data book beserta review nya, maka kita harus melakukan request sebanyak 2x yaitu melakukan request ke service book lalu request kembali ke service review. Biasanya model seperti ini akan membuat banyak latency di bagian client, nah untuk mengurangi hal tersebut maka kita cukup melakukan merge request API di bagian API gateway sehingga client hanya perlu melakukan request sekali ke API gateway, biasanya saya akan melakukan merge request API dengan menggunakan RxJava, contohnya adalah seperti berikut.
Mungkin ada yang bertanya - tanya, mengapa menggunakan redis ?, yups untuk menyimpan sebuah session yang berupa token, terdapat beberapa pendekatan yaitu kita dapat menyimpan token tersebut pada database atau dapat juga disimpan ke dalam redis. Jika menggunakan database maka database nya harus disharing antar service, ini mungkin pekerjaan yang lumayan merepotkan jika kita memiliki banyak service. Alternatif lain adalah menggunakan redis, dimana redis ini akan kita buat di 1 server sendiri.
Bagaimana Menyimpan Session Pada Redis ?
Nah lagi - lagi spring menyediakan kebutuhan session, di spring ada namanya spring-session, dimana kita dapat menyimpan session langsung ke redis. Lalu bagaimana dengan konfigurasi OAuth2 ? apakah token nya dapat disimpan ke redis ? jawaban nya adalah sangatlah mungkin, cara nya adalah dengan menggunakan token store seperti berikut.
Sehingga apabila anda berhasil melakukan authentikasi, maka token anda akan disimpan ke redis, ingat bahwa token ini memiliki masa nya tersendiri sehingga hanya dapat digunakan untuk waktu tertentu saja.
Bagaimana service lain seperti service book dan service review tau bahwa token yang dikirim oleh client adalah token hasil yang digenerate oleh authorization server ?
Yups lagi - lagi kita menggunakan fungsi spring-session untuk menghandle masalah seperti ini, di bagian service - service kita hanya perlu mendeklarasikan resource id dan juga konfigurasi OAuth2 seperti berikut.
CATATAN : setiap service wajib memiliki 1 resource id, dimana resource id ini akan didaftarkan ke authorization server. Pencatatan resource id ini berfungsi sebagai memberikan batasan kepada client tertentu, sehingga client tertentu hanya boleh mengakses resource tertentu, contohnya adalah jika client seperti mobile atau web langsung mengakses service book maka tidak diperbolehkan dikarenakan client seperti mobile atau web tidak memiliki resource id dari service book, yang memiliki resource id service book adalah API gateway, sehingga client seperti mobile atau web hanya bisa mengakses melalui API gateway.
Untuk source code diatas dapat anda akses di Simple API Gateway. Sekian artikel mengenai Belajar API Gateway, jika ada saran dan komentar silahkan isi dibawah dan terima kasih :)