Pada artikel sebelumnya penulis telah membahas mengenai bahasa pemrograman swift versi 3. Pada artikel ini, penulis akan membahas bagaimana cara membuat aplikasi iOS sederhana :).

Kebutuhan Project

Pada dasarnya, swift dapat dijalankan di linux dan OSX, akan tetapi ketika kita mulai ingin membangun sebuah aplikasi iOS maka kita membutuhkan sistem operasi OSX. Mengapa demikian ? karena untuk membuat aplikasi iOS membutuhkan IDE Xcode, mungkin ada yang bertanya, apakah kita dapat membuat aplikasi iOS tanpa Xcode ? ya bisa saja seperti menggunakan AppCode punya jetbrains, akan tetapi kita diharuskan semuanya untuk ngoding mulai dari logic hingga UI nya :(, berbeda dengan Xcode yang akan memberikan fitur UI layaknya android studio :D. Penulis menyarankan anda untuk menggunakan Xcode untuk development iOS, terdapat banyak fitur salah satunya adalah Xcode dapat memberitahukan kepada kita jika layout yang kita buat tidak responsive bahkan dia dapat mengetahui jika tata letak suatu komponent tidak sesuai dengan letaknya :). Wow… mungkin fitur Xcode bahkan bisa dibilang lebih lengkap dari android studio, oke berikut adalah kebutuhan project untuk development iOS.

  • MacBook / Laptop dengan Hackintosh, disarankan menggunakan OSX sierra
  • Xcode terbaru, pada artikel ini penulis menggunakan Xcode versi 8.3.2
  • secangkir kopi untuk bersantai :D

Tahap - Tahap Development

Kira - kira kita akan membuat apa ya ? ya, pada artikel ini, kita akan membuat sebuah aplikasi untuk menampilkan lagu - lagu yang ada di spotify :D. Bagaimana cara nya kita dapat mendapatkan datanya ? :o, gampang kok, kita hanya perlu mengakses API yang telah disediakan oleh spotify disini, karena kita hanya akan menampilkan item tertentu maka kita akan menggunakan API search yang ada pada spotify yaitu API yang ada disini. Pada API spotify, kita tidak diharuskan untuk login terkecuali jika berhubungan dengan data user :). Berikut adalah tahapan development yang akan kita lakukan.

  • Membuat Project iOS dengan Xcode
  • Melakukan Instalasi Dependency Dengan Cocoapods
  • Membuat Model Response
  • Membuat Service / Consume API
  • Membuat View Dengan Multi StoryBoard Dan Navigation
  • Membuat Controller
  • Uji Coba Aplikasi

Membuat Project iOS dengan Xcode

Hal yang pertama kita lakukan adalah membuat project dengan Xcode. Silahkan buka Xcode anda maka akan muncul tampilan seperti berikut.

Screen Shot 2017-03-31 at 10.29.11 PM.png

Lalu pilih create a new Xcode project maka akan muncul menu seperti berikut.

Screen Shot 2017-03-31 at 10.31.17 PM.png

Lalu pilih single view application lalu klik next dan muncul menu untuk pengisian deskripsi aplikasi, silahkan isi seperti berikut.

Screen Shot 2017-03-31 at 10.33.39 PM.png

Jika berhasil maka akan muncul menu project seperti berikut.

Screen Shot 2017-03-31 at 10.34.24 PM.png

Melakukan Instalasi Dependency Dengan Cocoapods

Terkadang pada sebuah project yang kita buat, kita membutuhkan dependency library dari pihak lain misalnya seperti Alamofire untuk consume API dan lain sebagainya. Setiap bahasa pemrograman mempunya tool tersendiri, begitu pula dengan swift, di swift kita dapat menggunakan Cocoapods sebagai dependency management karena Cocoapods salah satu tool yang sangat banyak digunakan oleh kalangan developer iOS.

Untuk melakukan instalasi Cocoapods, kita dapat menggunakan fungsi gem yang secara default telah tersedia di OSx, silahkan jalankan perintah berikut untuk melakukan instalasi cocoapods.

gem install cocoapods

Setelah selesai, silahkan close project Xcode anda, lalu akses folder project iOS anda dan jalankan perintah berikut untuk membuat konfigurasi cocoapods.

pod init

Maka akan terbentuk sebuah file yaitu Podfile langka selanjutnya silahkan buka file Podfile tersebut lalu silahkan ubah konfigurasi seperti berikut.

# Uncomment the next line to define a global platform for your project
 platform :ios, '10.0'

target 'Belajar-iOS' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for Belajar-iOS
  pod 'RxSwift',    '~> 3.0'
  pod 'RxCocoa',    '~> 3.0'
  pod 'ObjectMapper', '~> 2.2'
  pod 'Alamofire', '~> 4.4'
  pod 'AlamofireObjectMapper', '~> 4.0'
  pod 'Kingfisher', '~> 3.0'
  pod 'SwiftOverlays', '~> 3.0.0'
  pod 'AudioPlayerManager'
  pod 'MarqueeLabel/Swift'

  target 'Belajar-iOSTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'Belajar-iOSUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end

Berikut adalah beberapa penjelasan dari konfigurasi diatas :

  • platform : mendefiniskan versi iOS yang akan kita gunakan
  • RxSwift : berfungsi sebagai manipulasi UI Events dan untuk menghandle response API
  • RxCocoa : berfungsi sebagai library tambahan untuk mendukung RxSwift karena kita menggunakan Cocoapods
  • ObjectMapper : berfungsi untuk melakukan mapping json
  • Alamofire : berfungsi untuk mengakses API
  • AlamofireObjectMapper : berfungsi untuk mengubah response dari alamofire menjadi object swift
  • Kingfisher : berfungsi untuk cache gambar
  • SwiftOverlays : berfungsi untuk animasi loading
  • AudioPlayerManager : berfungsi untuk memutarkan lagu
  • MarqueeLabel : berfungsi untuk membuat text marquee

Oke, selanjutnya silahkan jalankan perintah berikut untuk melakukan instalasi dependency diatas.

pod install

Silahkan buka folder project anda, jika berhasil maka akan muncul sebuah workspace seperti berikut.

Screen Shot 2017-03-31 at 11.03.41 PM.png

Lalu silahkan klik kanan pada Belajar-iOS.xcworkspace tersebut lalu open with Xcode maka tampilan project anda akan seperti berikut.

Screen Shot 2017-03-31 at 11.06.02 PM.png

Membuat Model Response

Setelah selesai dengan dependency management, langkah selanjutnya kita akan membuat model response dimana sebenarnya model response ini adalah representasi dari response json yang berasal dari API. Berikut adalah contoh json yang dihasilkan dari API spotify.

{
  "tracks": {
    "href": "https://api.spotify.com/v1/search?query=Coldplay&type=track&offset=0&limit=20",
    "items": [
      {
        "album": {
          "album_type": "single",
          "artists": [
            {
              "external_urls": {
                "spotify": "https://open.spotify.com/artist/69GGBxA162lTqCwzJG5jLp"
              },
              "href": "https://api.spotify.com/v1/artists/69GGBxA162lTqCwzJG5jLp",
              "id": "69GGBxA162lTqCwzJG5jLp",
              "name": "The Chainsmokers",
              "type": "artist",
              "uri": "spotify:artist:69GGBxA162lTqCwzJG5jLp"
            },
            {
              "external_urls": {
                "spotify": "https://open.spotify.com/artist/4gzpq5DPGxSnKTe4SA8HAU"
              },
              "href": "https://api.spotify.com/v1/artists/4gzpq5DPGxSnKTe4SA8HAU",
              "id": "4gzpq5DPGxSnKTe4SA8HAU",
              "name": "Coldplay",
              "type": "artist",
              "uri": "spotify:artist:4gzpq5DPGxSnKTe4SA8HAU"
            }
          ],
          "available_markets": [
            "AD",
            "AR",
            "AT",
            "AU",
            "BE",
            "BG",
            "BO",
            "BR",
            "CA",
            "CH",
            "CL",
            "CO",
            "CR",
            "CY",
            "CZ",
            "DE",
            "DK",
            "DO",
            "EC",
            "EE",
            "ES",
            "FI",
            "FR",
            "GB",
            "GR",
            "GT",
            "HK",
            "HN",
            "HU",
            "ID",
            "IE",
            "IS",
            "IT",
            "JP",
            "LI",
            "LT",
            "LU",
            "LV",
            "MC",
            "MT",
            "MX",
            "MY",
            "NI",
            "NL",
            "NO",
            "NZ",
            "PA",
            "PE",
            "PH",
            "PL",
            "PT",
            "PY",
            "SE",
            "SG",
            "SK",
            "SV",
            "TR",
            "TW",
            "US",
            "UY"
          ],
          "external_urls": {
            "spotify": "https://open.spotify.com/album/7IzpJkWQqgz1BTutQvSitX"
          },
          "href": "https://api.spotify.com/v1/albums/7IzpJkWQqgz1BTutQvSitX",
          "id": "7IzpJkWQqgz1BTutQvSitX",
          "images": [
            {
              "height": 640,
              "url": "https://i.scdn.co/image/a57625bbecee7b4e7fe932a31cd92319d2a32855",
              "width": 640
            },
            {
              "height": 300,
              "url": "https://i.scdn.co/image/4c45b4ad2a79f5a345e854180cec249731db1908",
              "width": 300
            },
            {
              "height": 64,
              "url": "https://i.scdn.co/image/cd7345b44b0e950735295029bfd96b5d174bead6",
              "width": 64
            }
          ],
          "name": "Something Just Like This",
          "type": "album",
          "uri": "spotify:album:7IzpJkWQqgz1BTutQvSitX"
        },
        "artists": [
          {
            "external_urls": {
              "spotify": "https://open.spotify.com/artist/69GGBxA162lTqCwzJG5jLp"
            },
            "href": "https://api.spotify.com/v1/artists/69GGBxA162lTqCwzJG5jLp",
            "id": "69GGBxA162lTqCwzJG5jLp",
            "name": "The Chainsmokers",
            "type": "artist",
            "uri": "spotify:artist:69GGBxA162lTqCwzJG5jLp"
          },
          {
            "external_urls": {
              "spotify": "https://open.spotify.com/artist/4gzpq5DPGxSnKTe4SA8HAU"
            },
            "href": "https://api.spotify.com/v1/artists/4gzpq5DPGxSnKTe4SA8HAU",
            "id": "4gzpq5DPGxSnKTe4SA8HAU",
            "name": "Coldplay",
            "type": "artist",
            "uri": "spotify:artist:4gzpq5DPGxSnKTe4SA8HAU"
          }
        ],
        "available_markets": [
          "AD",
          "AR",
          "AT",
          "AU",
          "BE",
          "BG",
          "BO",
          "BR",
          "CA",
          "CH",
          "CL",
          "CO",
          "CR",
          "CY",
          "CZ",
          "DE",
          "DK",
          "DO",
          "EC",
          "EE",
          "ES",
          "FI",
          "FR",
          "GB",
          "GR",
          "GT",
          "HK",
          "HN",
          "HU",
          "ID",
          "IE",
          "IS",
          "IT",
          "JP",
          "LI",
          "LT",
          "LU",
          "LV",
          "MC",
          "MT",
          "MX",
          "MY",
          "NI",
          "NL",
          "NO",
          "NZ",
          "PA",
          "PE",
          "PH",
          "PL",
          "PT",
          "PY",
          "SE",
          "SG",
          "SK",
          "SV",
          "TR",
          "TW",
          "US",
          "UY"
        ],
        "disc_number": 1,
        "duration_ms": 247626,
        "explicit": false,
        "external_ids": {
          "isrc": "USQX91700278"
        },
        "external_urls": {
          "spotify": "https://open.spotify.com/track/1dNIEtp7AY3oDAKCGg2XkH"
        },
        "href": "https://api.spotify.com/v1/tracks/1dNIEtp7AY3oDAKCGg2XkH",
        "id": "1dNIEtp7AY3oDAKCGg2XkH",
        "name": "Something Just Like This",
        "popularity": 97,
        "preview_url": "https://p.scdn.co/mp3-preview/499eefd42a24ec562c464bd7acfad7ed41eb9179?cid=null",
        "track_number": 1,
        "type": "track",
        "uri": "spotify:track:1dNIEtp7AY3oDAKCGg2XkH"
      }
    ],
    "limit": 20,
    "next": "https://api.spotify.com/v1/search?query=Coldplay&type=track&offset=20&limit=20",
    "offset": 0,
    "previous": null,
    "total": 4618
  }
}

Kita tidak akan menggunakan semua value diatas, kita hanya akan menampilkan track, nama artist, nama album, judul album, gambar album dan akan memutarkan contoh lagu nya. Silahkan klik kanan pada Folder Belajar-iOS yang berwarna kuning lalu pilih New Group dan rename menjadi models. Setelah selesai, silahkan klik kanan pada group model lalu pilih menu New File, silahkan pilih menu Swift File, kemudian untuk menetukan direktory, anda harus membuat folder terlebih dahulu sehingga group models akan direpresentasikan ke folder models, berikan nama TrackResponse pada file swift yang anda buat, kemudian masukkan codingan seperti berikut.

//
//  TrackResponse.swift
//  Belajar-iOS
//
//  Created by rizki mufrizal on 4/30/17.
//  Copyright © 2017 rizki mufrizal. All rights reserved.
//

import Foundation
import ObjectMapper

struct TrackResponse: Mappable {
    var tracks: Track?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {
        tracks <- map["tracks"]
    }
}

struct Track: Mappable {
    var limit: Int?
    var next: String?
    var offset: Int?
    var previous: String?
    var total: Int?
    var items: [Item]?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {
        limit <- map["limit"]
        next <- map["next"]
        offset <- map["offset"]
        previous <- map["previous"]
        total <- map["total"]
        items <- map["items"]
    }
}

struct Item: Mappable {
    var name: String?
    var previewUrl: String?
    var album: Album?
    var artists: [Artist]?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {
        name <- map["name"]
        previewUrl <- map["preview_url"]
        album <- map["album"]
        artists <- map["artists"]
    }
}

struct Artist: Mappable {
    var name: String?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {
        name <- map["name"]
    }
}

struct Album: Mappable {
    var name: String?
    var images: [Image]?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {
        name <- map["name"]
        images <- map["images"]
    }
}

struct Image: Mappable {
    var height: Int?
    var width: Int?
    var url: String?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {
        height <- map["height"]
        width <- map["width"]
        url <- map["url"]
    }
}

Akhirnya selesai juga untuk class response nya :D. Artikel selanjutnya akan membahas mengenai bagaimana cara membuat service, view dan controller nya :). Untuk source code diatas dapat anda akses di Belajar-iOS. Sekian artikel mengenai Belajar iOS bagian 1, jika ada saran dan komentar silahkan isi dibawah dan terima kasih :)

Bermula dari project yang sedang saya kerjakan di kantor yaitu aplikasi iOS, pada kesempatan ini saya akan share sedikit mengenai dasar - dasar pada swift :D.

Apa Itu Swift ?

Swift adalah bahasa pemrograman yang digunakan untuk membangun aplikasi untuk produk apple seperti iOS, OSX dan lain sebagainya.

Terdapat 2 bahasa pemrograman yang dapat kita gunakan untuk mengembangkan aplikasi untuk produk apple yaitu Objective-C dan Swift. Pada artikel ini, penulis hanya membahas mengenai bahasa pemrograman swift untuk versi 3, untuk migrasi versi swift 3 silahkan lihat di migration swift 3.

Mengapa Menggunakan Swift ?

Mungkin beberapa developer swift pemula pasti akan bertanya, mengapa kita menggunakan swift ? mengapa tidak menggunakan Objective-C ?, Baiklah kita akan membahas satu - persatu.

Pada zaman sekarang, para developer core dari berbagai bahasa pemrograman akan membuatkan sebuah bahasa dimana bahasa ini lebih mudah dimengerti manusia, berbeda dengan developer apple, mereka membuat bahasa pemrograman swift ini sendiri lebih dekat dengan mesin layaknya bahasa C, C++ dan Objective-C sehingga akan meningkatkan performance dari aplikasi.

Swift sendiri dibangun dengan paradigma yang berbeda dengan Objective-C, dimana bahasa pemrograman swift lebih mudah dibaca jika anda beralirah ke bahasa pemrograman berorientasi object seperti java, javascript, ruby dan lain sebagainya. Jika anda dulu nya adalah developer bahasa C atau C++ maka anda akan lebih mudah membaca source code Objective-C. Jika anda adalah developer pemula, penulis sarankan untuk mempelajari bahasa pemrograman swift 3 karena Objective-C dan swift adalah bahasa pemrograman yang berbeda dan tidak ada kaitan dari kedua nya.

Jika anda adalah seorang developer android, terlebih jika anda telah terbiasa menggunakan bahasa pemrograman kotlin maka anda tidak akan terlalu susah jika migrasi dari android ke iOS. Bahkan anda akan memiliki learning curve yang lebih cepat.

Latihan Swift

Pada artikel ini, penulis menggunakan IBM Swift Sandbox karena kita hanya akan latihan cli dengan menggunakan bahasa pemrograman swift 3. IBM Swift Sandbox adalah salah satu editor cli online untuk latihan bahasa pemrograman swift, disana terdapat 2 versi yaitu swift versi 2 dan versi 3. Pada artikel ini, penulis akan menggunakan swift 3.

Latihan Variabel Pada Swift

Secara default, pada IBM Swift Sandbox akan menampilkan source code seperti berikut.

print("Hello world!")

Source code diatas berfungsi untuk menampilkan sebuah tulisan Hello Word! :-). Tahap selanjutnya tulisankan code seperti berikut.

let nama: String = "rizki mufrizal"
print(nama)

Codingan diatas berfungsi untuk membuat sebuah variabel dengan tipe data string, lalu kita inisialisasi dengan sebuah string lalu kita tampilkan. Di dalam swift terdapat 2 cara untuk mendeklarasikan variabel yaitu dengan menggunakan let dan var, dimana let berfungsi sebagai constanta atau immutable sehingga hanya bisa diinisialisasi sekali saja, berbeda dengan var yang bersifat mutable sehingga dapat diubah - ubah. Silahkan ubah source code diatas menjadi seperti berikut.

let nama: String = "rizki mufrizal"
nama = "ganti aja"
print(nama)

maka akan muncul error seperti berikut.

ERROR at line 5, col 6: cannot assign to value: 'nama' is a 'let' constant
nama = "ganti aja"
~~~~ ^
NOTE at line 4, col 1: change 'let' to 'var' to make it mutable
let nama: String = "rizki mufrizal"
^~~
var

Lalu silahkan ubah seperti berikut.

var nama: String = "rizki mufrizal"
nama = "ganti aja"
print(nama)

maka hasil nya akan sukses dikarenakan kita ingin mengubah value yang ada di dalam variabel nama.

Latihan Function Pada Swift

Sama seperti bahasa lain, swift juga dapat menggunakan function / method. Function / method pada swift juga dapat mengembalikan nilai berdasarkan tipe data nya dan juga dapat berupa void atau tidak mengembalikan nilai.

Berikut adalah contoh jika mengambalikan nilai.

func perjumlahan(angka1: Int, angka2: Int) -> Int {
    return angka1 + angka2
}
print("hasilnya adalah : \(perjumlahan(angka1: 2, angka2: 3))")

Diatas adalah contoh jika kita mengembalikan nilai, dan pada source code diatas kita menggunakan fungsi \() dimana fungsi tersebut adalah fungsi untuk mengeksekusi sebuah function atau variabel yang berada di dalam sebuah string atau “” (kutip dua).

Berikut adalah contoh jika function / method yang tidak mengembalikan nilai.

func perjumlahan(angka1: Int, angka2: Int) {
    print("hasilnya adalah : \(angka1 + angka2)")
}
perjumlahan(angka1: 2, angka2: 3)

Latihan Array Pada Swift

Pada latihan ini, kita akan membuat sebuah struct / record. Apa itu struct / record ?

Struct / record adalah kumpulan data dengan type yang berbeda

Sekilas memang mirip dengan array, akan tetepi terdapat perbedaan dimana array mempunyai banyak data dengan type data yang sama sedangkan struct / record memiliki data yang banyak dan memiliki type data yang berbeda. Jika kita menggunakan java, maka struct / record sama dengan class domain / entity / pojo. Berikut adalah contoh penggunaan array struct pada swift 3.

struct Barang {
    var idBarang: String?
    var namaBarang: String?
    var jumlahBarang: Int?
}

var barangs = [Barang]()

barangs.append(Barang(idBarang: "B001", namaBarang: "Rinso", jumlahBarang: 10))

for b in barangs {
    print("id Barang     : \(b.idBarang)")
    print("Nama Barang   : \(b.namaBarang)")
    print("Jumlah Barang : \(b.jumlahBarang)")
}

Maka hasilnya akan seperti berikut.

id Barang     : Optional("B001")
Nama Barang   : Optional("Rinso")
Jumlah Barang : Optional(10)

Agar tulisan Optional hilang maka tambahkan ! seperti berikut.

struct Barang {
    var idBarang: String?
    var namaBarang: String?
    var jumlahBarang: Int?
}

var barangs = [Barang]()

barangs.append(Barang(idBarang: "B001", namaBarang: "Rinso", jumlahBarang: 10))

for b in barangs {
    print("id Barang     : \(b.idBarang!)")
    print("Nama Barang   : \(b.namaBarang!)")
    print("Jumlah Barang : \(b.jumlahBarang!)")
}

Maka hasilnya akan seperti berikut.

id Barang     : B001
Nama Barang   : Rinso
Jumlah Barang : 10

Sekian artikel mengenai Belajar Swift, jika ada saran dan komentar silahkan isi dibawah dan terima kasih :)

Pada artikel ini, penulis akan membahas mengenai salah satu protokol Authorization yang banyak digunakan dikalangan developer. Sebelum memasuki pembahasan mengenai OAuth2, kita akan membahas terlebih dahulu mengenai Authentication dan Authorization.

Apa Itu Authentication ?

Authentication adalah suatu proses untuk menentukan identitas seseorang.

Untuk menentukan identitas seseorang kita dapat menggunakan kerahasiaan informasi seperti contoh berikut

Kerahasiaan Informasi Deskripsi
Password Hanya pengguna yang mengetahui password
PIN Hanya pengguna yang mengetahui PIN
private key hanya pengguna yang memiliki private key

Dari kerahasiaan informasi diatas, kita dapat menentukan identitas seseorang, misalnya ketika seseorang login pada sebuah aplikasi, jika dia menggunakan username dan password yang benar maka sudah dipastikan bahwa yang login tersebut adalah pengguna sebenarnya.

Selain kerahasiaan informasi, untuk menentukan identitas seseorang kita dapat menggunakan keunikan dari seorang pengguna, contohnya.

Keunikan Informasi Deskripsi
Retina Hanya dimiliki oleh satu pengguna
Fingerprint Hanya dimiliki oleh satu pengguna

Setiap pengguna pasti mempunyai keunikan informasi seperti fingerprint, dimana fingerprint antara 1 pengguna dengan pengguna lain pasti memiliki perbedaan. Perbedaan ini dapat kita lihat dari garis - garis sidik jari yang berbeda - beda.

Apa Itu Authorization ?

Authorization adalah proses dimana kita akan memberikan hak akses kepada pihak ketiga untuk dapat melakukan akses data yang kita miliki.

Proses authorization akan dilakukan jika anda telah melakukan authentication, karena authentication diperlukan untuk identifikasi user yang akan memberikan hak akses datanya. Berikut adalah contoh penggunaan authorization, misalnya anda memiliki akun google, kemudian anda ingin melakukan registrasi pada layanan web lain, pada web tersebut terdapat fitur login/register dengan menggunakan akun google, maka kita dapat menggunakan fitur tersebut. Pada saat fitur tersebut kita gunakan maka nantinya google akan menanyakan apakah kita memberikan hak akses agar aplikasi tersebut dapat mengakses data kita yang terdapat pada google. Jika memberikan hak akses maka web tersebut akan mendapatkan data kita, jika tidak maka google tidak akan memberikan data anda. Proses diatas adalah salah satu contoh dari proses authorization pada aplikasi.

Apa Itu OAuth2 ?

OAuth2 adalah kepanjangan dari open authorization dimana OAuth2 banyak digunakan dikalangan developer sebagai proses authorization sebuah aplikasi.

Dengan menggunakan protokol ini, maka aplikasi pihak ketiga dapat mengakses data dari aplikasi yang telah kita bangun. Di dalam OAuth2 terdapat beberapa grant type diantaranya adalah :

Grant Type Authorization Code

Pada grant type ini, kita akan menggunakan generate code yang berasal dari authorization server untuk ditukarkan dengan sebuah token, dimana token ini kita gunakan untuk mengakses sebuah resource / API.

Berikut adalah gambar flow untuk Authorization Code :

oauth_authorization_code

Gambar diatas saya ambil dari dokumentasi oracle. Gambar diatas menjelaskan bahwa ketika kita menggunakan OAuth2, maka kita seharusnya menggunakan 2 server, yaitu yang satu bertugas sebagai authorization server, dimana server ini yang akan memberikan hak akses kepada apilkasi pihak ketiga. Sedangkan server yang satu nya lagi sebagai resource server atau sebagai penyedia API.

Ketika ada aplikasi pihak ketiga akan mengakses API, API akan terlebih dahulu bertanya kepada authorization server, apakah token yang dikirim valid atau tidak, jika valid maka resource server akan memberikan resource yang dibutuhkan dan jika teryata tidak valid maka akan menampilkan bahwa aplikasi tersebut tidak berhak melakukan akses terhadap resource tersebut.

Pada flow ini, user nantinya akan melakukan login pada authorization server, dimana url pada login tersebut terdapat client id dan authorization type dari aplikasi yang akan akan mengakses resource tersebut. Ketika user melakukan approve, authorization server akan melakukan redirect ke aplikasi pihak ketiga dengan membawa sebuah code, dimana code ini akan digunakan oleh aplikasi pihak ketiga untuk menukarkan nya dengan access token, setelah berhasil ditukarkan maka code ini tidak dapat digunakan lagi. Setelah mendapatkan access token, aplikasi pihak ketiga dapat melakukan akses terhadap resource yang telah di approve. Authorization Code biasanya digunakan oleh aplikasi - aplikasi yang dapat menyimpan client id dan client secret secara aman, contonya seperti Java, NodeJS, Ruby, PHP, dan lain sebagainya.

Grant Type Resource Owner Password Credentials

Pada grant type ini, kita akan menggunakan username dan password langsung dari owner nya. Grant type ini biasanya digunakan jika aplikasi yang dibangun merupakan aplikasi pribadi atau pembuat aplikasi berasal dari perusahaan yang sama, contohnya adalah ketika kita melakukan login pada aplikasi facebook.

Flow ini tidak direkomendasikan lagi dikarenakan aplikasi pihak ketiga diharuskan mengirimkan username dan password user sehingga memungkinkan aplikasi pihak ketiga dapat menggunakan akun owner nya. berikut adalah gambar flow grant type resource owner password credentials yang saya ambil dari dokumentasi oracle.

oauth_resource_owner_password_credentials.png

Grant Type Client Credentials

Grant type selanjutnya adalah client credentials, dimana grant type ini biasanya digunakan oleh aplikasi - aplikasi yang telah menjalin kerja sama dengan suatu perusahaan. Masing - masing aplikasi pihak ketiga akan mendapatkan client id dan client secret, dengan menggunakan client id dan client secret, mereka menukarkan nya dengan access token, pada flow ini, tidak diberikan refresh token, hanya terdapat access token, sehingga apabila access token expired maka mereka diwajibkan untuk mengirim kembali client id dan client secret tersebut untuk ditukarkan dengan access token. berikut adalah gambar grant type client credentials yang saya ambil dari dokumentasi oracle.

oauth_client_credentials.png

Grant Type Implicit Client

Grant type yang terakhir adalah implicit client, grant type ini biasanya digunakan untuk client yang tidak dapat menyimpan client secret dengan aman, contohnya seperti Angular JS, Vue JS, React JS dan lain sebagainya. Pada flow ini, terdapat beberapa langkah yang akan dijalankan, berikut adalah langkah - langkahnya :

  • user mengakses aplikasi pihak ketiga dan melakukan login.
  • aplikasi pihak ketiga akan melakukan redirect ke halaman login authorization server
  • user melakukan approve
  • aplikasi pihak ketiga mendaptkan code, kemudian ditukarkan dengan access token
  • aplikasi pihak ketiga mengakses resource dengan access token tersebut
  • resource server akan menanyakan apakah access token valid atau tidak kepada authorization server.

Pada grant type ini, biasanya authorization server tidak akan memberikan refresh token dikarenakan penyimpanan refresh token yang tidak aman. Berikut adalah gambar grant type implicit client yang saya ambil dari dokumentasi digital ocean.

oauth2_implicit_client.png

Kata - Kata Asing Pada OAuth2

Pada tulisan diatas terdapat beberapa kata - kata asing, berikut adalah penjelasan nya.

  • Client id : adalah id yang mewakili dari 1 client yang akan mengakses resource / API
  • Client Secret : adalah pasangan dari client id, bisa disebut juga sebagai password nya
  • access token : token yang digenerate oleh authorization server, token ini memiliki massa nya sehingga tidak dapat digunakan dalam jangka waktu yang lama.
  • refresh token : token ini digunakan untuk meminta access token yang baru dikarenakan access token yang lama telah expired.
  • resource server : server yang menyediakan data / API.
  • authorization server : server yang melakukan pengecekan authentication dan authorization.

Best Practice Implementasi OAuth2

Best practice yang saya buat pada artikel ini berasal dari flow teknologi Spring OAuth2. Mungkin beberapa dari anda akan bertanya, mengapa menggunakan spring ? mengapa tidak menggunakan teknologi lain ?, yups menurut pengalaman saya, dari beberapa project yang pernah saya kerjakan, spring adalah salah satu framework yang sangat banyak menyediakan fitur - fitur yang dibutuhkan terutama untuk kebutuhan OAuth2 dibandingkan framework lain misalnya seperti sails js, express js dan sebagainya. Contohnya jika pada node js, saya menggunakan oauth2orize, dimana library tersebut tidak menyediakan schema database dan tidak support untuk strategy in memory token store dan remote token service, Sehingga kita wajib membuat schema tersendiri dan harus menyesuaikan sendiri.

Strategi OAuth2

Strategi yang biasanya saya gunakan jika menggunakan Spring OAuth2 :

  • Authorization dan Resource server berada di dalam 1 war / aplikasi, contoh ini biasanya menggunakan in memory token sehingga antara Authorization dan Resource server biasanya saling bekerja sama.
  • Authorization dan Resource server berada pada server yang berbeda atau dapat dikatakan bahwa mereka berbeda war / aplikasi. Untuk metode ini, kita mempunyai 3 strategi yaitu :
    • Remote token service, dimana Authorization server akan menggunakan in memory token, resource server akan melakukan pengecekan melalui protokol http apakah token valid atau invalid.
    • Sharing database, biasanya saya akan menggunakan strategi ini, mengapa demikian ? dikarenakan saya biasanya ingin agar data seperti grant type, expired token dan lain nya dapat berjalan secara dinamis sehingga kita tidak perlu ribet untuk mengubah codingan lagi. Schema OAuth2 pada Spring OAuth2 dapat anda lihat di schema sql atau anda dapat menggunakan schema yang saya gunakan di schema sql.
    • Http Session Redis, pada strategi ini biasanya antara resource dan authorization server akan melakukan koneksi ke redis, dimana semua token akan disimpan ke redis. Apabila resource server akan diakses, resource server akan melakkan pengecekan pada redis. Jika anda menggunakan spring maka anda dapat menggunakan Spring Session. Ketika anda melakukan authentication, jika credential anda sesuai maka token akan disimpan ke redis, ketika token tersebut expired maka token tersebut akan dihapus dari redis.

Penggunaan Token

Setiap client biasanya bisa memiliki lebih dari 1 grant type yang telah kita jelaskan diatas. Bagaimana jika client memiliki banyak aplikasi, apakah setiap token yang digenerate akan disimpan di database ? bagaimana jika client tersebut memiliki banyak grant type ? nah ini merupakan dilema yang pernah saya temui pada saat membangun OAuth2 pada node js dikarenakan saya membuatnya mulai dari 0. Dikarenakan saya masih kurang paham mengenai OAuth2, saya mencoba membuat sebuah project OAuth2 dengan strategy sharing database pada Spring OAuth2, dan teryata flow dari Spring OAuth2 telah terstruktur, bahkan spring OAuth2 menyediakan custom token dengan menggunakan token extractor, tidak hanya custom token, kita juga dapat melakukan custom output token, misalnya kita ingin token yang digenerate adalah token JWT (Json Web Token). Berikut adalah flow yang harus anda terapkan jika anda membuat OAuth2 secara manual dengan menggunakan sharing database, flow ini berdasarkan referensi dari Spring OAuth2.

  • Silahkan buat schema database seperti schema Spring OAuth2 diatas.
  • Setiap grant type, hanya memiliki 1 access token dan refresh token.
  • Pada saat generate token, kita akan melakukan pengecekan terlebih dahulu pada database, jika client id suatu client memiliki token maka kita akan cek apakah token tersebut telah expired atau belum, jika expired maka kita akan generate ulang token, token yang baru akan diupdate di database dan token tersebut kita berikan kepada client tersebut, jika token tidak expired maka kita tinggal mengembalikan token tersebut, jika token belum tersedia berdasarkan client id dan grant type maka kita generate token baru dan simpan ke database.
  • Pada saat refresh token, kita juga akan cek terlebih dahulu, apakah token telah expired atau belum, jika expired maka token baru akan digenerate dan diupdate yang ada di database, jika tidak expired maka kita kembalikan token yang ada di database.

Berdasarkan flow diatas, dapat kita simpulkan bahwa setiap 1 client bisa mempunyai banyak grant type. Dimana setiap 1 client dengan 1 grant type hanya memiliki 1 token yang berlaku meskipun mereka memiliki banyak aplikasi, Jadi jika si client mempunyai 4 grant type, maka dia memiliki 4 token dimana token tersebut mempunya hak akses yang berbeda - beda, bisa saja yang 1 hanya memiliki hak akses read, yang satu nya hanya untuk write dan yang satu nya lagi untuk read dan write.

Bagi anda yang ingin melihat contoh source code codingan, silahkan lihat di Spring OAuth2 Custom. Sekian artikel mengenai Belajar OAuth2, jika ada saran dan komentar silahkan isi dibawah dan terima kasih :)

Bicara mengenai database, seorang database administrator harus mengetahui seluk beluk dari database, salah satunya adalah proses backup dan restore database. Database tanpa backup adalah suatu hal yang sangat fatal dikarenakan jika suatu waktu terjadi sesuatu pada database production maka hilang sudah semua harapan :D. Pada artikel ini, penulis akan mencoba membuat sebuah backup data lalu kita akan restore.

Perlengkapan Project

Untuk membuat virtual database maka kita akan menggunakan docker, bagi anda yang belum mengerti tentang docker, silakan baca artikel Belajar Docker. Silahkan jalan docker anda, jika anda pengguna linux maka secara default service docker akan berjalan, jika anda pengguna osx maka anda harus menjalankan docker terlebih dahulu. Berikut adalah arsitektur yang akan kita gunakan untuk membuat backup dan restore database mongodb.

arsitektur-backup-restore.svg

Dari gambar diatas, kita dapat melihat bahwa nantinya akan ada 2 container, dimana container tersebut berisi database production dan database backup. Biasanya antara database production dan backup berada pada server yang berbeda.

Membuat Backup Database

Sebelum kita membuat backup database, kita akan melakukan setup docker terlebih dahulu, silahkan buka terminal anda, lalu jalankan perintah berikut untuk mendownload image mongodb.

docker pull mongo

Setelah selesai, silahkan anda membuat docker-compose.yml karena kita akan menggunakan docker compose. Isikan source code seperti berikut.

mongodb-production:
  container_name: mongodb-production
  image: mongo:latest
  ports:
    - 27000:27017

mongodb-backup:
  container_name: mongodb-backup
  image: mongo:latest
  links:
    - mongodb-production
  ports:
    - 27001:27017

Dari konfigurasi diatas dapat kita lihat bahwa container mongodb-backup membutuhkan dependency dari mongodb-production. Untuk menjalankan kedua docker diatas, silahkan gunakan perintah berikut.

docker-compose up

Jika berhasil maka di terminal anda akan muncul seperti berikut.

Screen Shot 2017-02-08 at 2.43.17 PM.png

Langkah selanjutnya kita akan membuat file shell script, bagi anda yang belum paham shell script, silahkan baca pada artikel Belajar Shell Script. Silahkan buat sebuah file dengan nama mongodb-backup.sh, kemudian isikan codingan seperti berikut.

#!/bin/bash
# author Rizki Mufrizal

HOST="127.0.0.1"
PORT="27017"
REMOTE_DB="2016"
USER=""
PASS=""
PATH_BACKUP="/var/database-backup"

mongodump --db=$REMOTE_DB --username=$USER --password=$PASS --host=$HOST --port=$PORT --out=$PATH_BACKUP

Untuk parameter environment seperti nama database, username, password dan lain - lain kita langsung membuat per variabel sehingga nantinya hanya perlu diubah pada bagian variabel saja. Untuk melakukan backup, kita akan menggunakan mongodump, dimana mongodump ini mempunya beberapa parameter diantaranya adalah database yang diremote, username, password, host, port dan folder backup. Karena file shell script ini akan kita gunakan di dalam container docker maka kita harus melakukan setting ulang dockernya. Silahkan buat sebuah file dengan nama Dockerfile kemudian isikan codingan seperti berikut.

FROM mongo:latest

RUN mkdir /backup-restore
WORKDIR /backup-restore
ADD . /backup-restore

Setelah selesai, sekarang jalankan perintah berikut untuk menghapus container yang lama.

docker stop $(docker ps -a -q) && docker rm $(docker ps -a -q)

Setelah selesai, kemudian kita akan membuat image baru dengan perintah berikut.

docker build -t rizki.mufrizal/mongo-backup .

Jika berhasil maka akan muncul output seperti berikut.

Sending build context to Docker daemon 10.24 kB
Step 1/4 : FROM mongo:latest
 ---> 59dbd3885751
Step 2/4 : RUN mkdir /backup-restore
 ---> Running in f7710c593a1b
 ---> 7eeacbf6f587
Removing intermediate container f7710c593a1b
Step 3/4 : WORKDIR /backup-restore
 ---> 89413f734f6d
Removing intermediate container 019a58f8d2ba
Step 4/4 : ADD . /backup-restore
 ---> c593b1efba36
Removing intermediate container 3129347a292d
Successfully built c593b1efba36

Karena ada perubahan konfigurasi, maka kita harus melakukan perubahan pada file docker-compose.yml seperti berikut.

mongodb-production:
  container_name: mongodb-production
  image: mongo:latest
  ports:
    - 27000:27017

mongodb-backup:
  container_name: mongodb-backup
  image: rizki.mufrizal/mongo-backup
  links:
    - mongodb-production
  ports:
    - 27001:27017

Lalu jalankan kembali docker compose dengan perintah.

docker-compose up

Test Backup Data

Setelah selesai melakukan konfigurasi, langkah selanjutnya kita akan mencoba mengakses database mongodb yang versi production dengan perintah berikut.

docker exec -i -t mongodb-production /bin/bash

Kemudian silahkan akses cli mongodb dengan perintah.

mongo

Kemudian jalankan perintah berikut untuk mengakses / membuat database.

use belajar-backup;

Kemudian untuk membuat sebuah collection, silahkan jalankan perintah berikut.

db.createCollection('tb_barang');

Untuk melakukan insert, silahkan jalankan perintah berikut.

db.tb_barang.insert(
  [
    { nama_barang: 'rinso', jumlah_barang: 10, harga_barang: 500 },
    { nama_barang: 'aqua', jumlah_barang: 50, harga_barang: 100 },
    { nama_barang: 'floridina', jumlah_barang: 10, harga_barang: 5000 }
  ]
);

Untuk melihat data di mongodb, anda dapat menggunakan perintah berikut.

db.tb_barang.find().pretty();

berikut adalah hasil outputnya.

{
	"_id" : ObjectId("589afba9f2586584e62c70da"),
	"nama_barang" : "rinso",
	"jumlah_barang" : 10,
	"harga_barang" : 500
}
{
	"_id" : ObjectId("589afba9f2586584e62c70db"),
	"nama_barang" : "aqua",
	"jumlah_barang" : 50,
	"harga_barang" : 100
}
{
	"_id" : ObjectId("589afba9f2586584e62c70dc"),
	"nama_barang" : "floridina",
	"jumlah_barang" : 10,
	"harga_barang" : 5000
}

Setelah selesai, sekarang saatnya untuk membuat backup database, silahkan akses cli mongodb yang versi backup dengan perintah berikut.

docker exec -i -t mongodb-backup /bin/bash

Secara otomatis kita akan berada di folder backup-restore, di dalam folder tersebut terdapat file mongodb-backup.sh yang telah kita buat, akan tetapi host yang digunakan pastinya akan berbeda dikarenakan berbeda container, untuk mengecek host database mongodb versi production silahkan jalankan perintah berikut.

printenv | grep MONGO

Berikut adalah hasil outputnya.

MONGODB_PRODUCTION_PORT_27017_TCP_PROTO=tcp
MONGO_VERSION=3.4.2
MONGODB_PRODUCTION_ENV_GPG_KEYS=0C49F3730359A14518585931BC711F9BA15703C6
MONGODB_PRODUCTION_ENV_GOSU_VERSION=1.7
MONGODB_PRODUCTION_PORT_27017_TCP_ADDR=172.17.0.2
MONGODB_PRODUCTION_ENV_no_proxy=*.local, 169.254/16
MONGO_PACKAGE=mongodb-org
MONGODB_PRODUCTION_NAME=/mongodb-backup/mongodb-production
MONGODB_PRODUCTION_PORT_27017_TCP_PORT=27017
MONGODB_PRODUCTION_ENV_MONGO_PACKAGE=mongodb-org
MONGODB_PRODUCTION_ENV_MONGO_MAJOR=3.4
MONGODB_PRODUCTION_PORT=tcp://172.17.0.2:27017
MONGO_MAJOR=3.4
MONGODB_PRODUCTION_ENV_MONGO_VERSION=3.4.2
MONGODB_PRODUCTION_PORT_27017_TCP=tcp://172.17.0.2:27017

Kemudian silahkan buka kembali file mongodb-backup.sh lalu ubah konfigurasinya seperti berikut.

#!/bin/bash
# author Rizki Mufrizal

HOST=${MONGODB_PRODUCTION_PORT_27017_TCP_ADDR}
PORT=${MONGODB_PRODUCTION_PORT_27017_TCP_PORT}
REMOTE_DB="belajar-backup"
USER=""
PASS=""
PATH_BACKUP="/var/database-backup"

mongodump --db=$REMOTE_DB --username=$USER --password=$PASS --host=$HOST --port=$PORT --out=$PATH_BACKUP

Setelah selesai, silahkan berikan hak akses untuk execute dengan perintah.

chmod a+x mongodb-backup.sh

Kemudian jalankan file tersebut dengan perintah.

./mongodb-backup.sh

Jika berhasil maka akan muncul output seperti berikut.

2017-02-08T13:00:52.092+0000	writing belajar-backup.tb_barang to
2017-02-08T13:00:52.095+0000	done dumping belajar-backup.tb_barang (3 documents)

Untuk memastikan bahwa database anda telah di backup, silahkan cek path folder backup anda, tadinya kita membuat path back up database di /var/database-backup, berikut adalah hasilnya jika berhasil.

Screen Shot 2017-02-08 at 8.04.14 PM.png

Melakukan Restore Database

Pada tahap sebelumnya kita telah berhasil membuat backup database, nah sekarang kita akan melakukan restore database, sebelumnya, untuk mempermudah kita akan menggunakan Robomongo untuk mengakses database production. Silahkan download dan lakukan instalasi, jika telah selesai, silahkan buka robomongo anda, lalu lakukan konfigurasi seperti berikut.

Screen Shot 2017-02-08 at 8.14.42 PM.png

mengapa kita menggunakan port 27000 ? ya dikarenakan konfigurasi forward port yang ada pada docker. Sehingga setiap kita mengakses port 27000 maka docker akan melakukan forward ke port 27017. Jika anda melakukan akses database dan collection nya maka akan muncul output seperti berikut.

Screen Shot 2017-02-08 at 8.15.21 PM.png

Sekarang silahkan klik kanan di databasenya kemudian pilih menu drop database, maka secara otomatis database dihapus, nah sekarang kita akan melakukan restore. Silahkan akses terminal untuk database mongodb versi backup. Kemudian jalankan perintah berikut untuk melakukan restore database.

mongorestore /var/database-backup/belajar-backup/ --host=${MONGODB_PRODUCTION_PORT_27017_TCP_ADDR} --port=${MONGODB_PRODUCTION_PORT_27017_TCP_PORT} --db="belajar-backup" --username="" --password=""

Jika berhasil maka akan muncul output seperti berikut.

2017-02-08T13:25:30.559+0000	the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead
2017-02-08T13:25:30.560+0000	building a list of collections to restore from /var/database-backup/belajar-backup dir
2017-02-08T13:25:30.561+0000	reading metadata for belajar-backup.tb_barang from /var/database-backup/belajar-backup/tb_barang.metadata.json
2017-02-08T13:25:32.837+0000	restoring belajar-backup.tb_barang from /var/database-backup/belajar-backup/tb_barang.bson
2017-02-08T13:25:32.841+0000	no indexes to restore
2017-02-08T13:25:32.841+0000	finished restoring belajar-backup.tb_barang (3 documents)
2017-02-08T13:25:32.841+0000	done

Output diatas menandakan bahwa database telah berhasil direstore :D. Sekian artikel mengenai Membuat Backup dan Restore Pada MongoDB, semoga bermanfaat dan terima kasih :)

Setelah sekian lama tidak update blog, nah kali ini penulis akan membuat sebuah artikel mengenai bagaimana cara membuat RESTful Web Service dengan menggunakan Framework Spring Boot :). Spring Boot merupakan salah satu project dari pivotal yaitu sebuah perusahaan yang mengembangkan framework spring. Bagi anda yang belum kenal dengan spring framework bisa membaca artikel di Belajar Spring Framework. Karena spring framework merupakan salah satu framework dari bahasa pemrograman java maka anda diwajibkan untuk melakukan instalasi java, bagi anda yang belum melakukan instalasi java dapat membaca artikel Instalasi Perlengkapan Coding Java.

Setup Project

Pada artikel ini, kita akan menggunakan groovy yaitu salah satu bahasa scripting yang dikembangkan diatas JVM (java virtual machine) dimana bahasa groovy ini dapat diinterpretasikan atau dikompilasi. Masih terdapat bahasa pemrograman lain yang dikembangkan diatas JVM seperti scala, kotlin, jruby, jython dan lain sebagainya. Di blog pribadi saya, terdapat salah satu pembahasan bahasa pemrograman diatas yaitu kotlin, bagi anda yang ingin membaca tentang kotlin, silahkan akses di Instalasi Perlengkapan Coding Kotlin.

Untuk melakukan setup project spring boot, kita dapat mengenerate projectnya melalui start spring.io. Silahkan isikan konfigurasi seperti berikut.

Screen Shot 2017-01-12 at 6.10.31 PM.png

Kemudian silahkan pilih menu generate project. Maka secara otomatis akan dibuatkan sebuah project spring boot dengan menggunakan bahasa pemrograman groovy :D. Disini kita akan menggunakan database mongodb dan menggunakan arsitektur HATEOAS (Hypermedia as the Engine of Application State). HATEOAS adalah salah satu constraint untuk membangun sebuah RESTful Web Service, dimana HATEOAS ini merupakan level 3 pada constraint RESTful Web Service. Pembahasan mengenai HATEOAS akan dibahas pada artikel berikutnya :).

Silahkan extract file yang telah didownload. Pada artikel ini, kita akan menggunakan IntellIJ IDE. Silahkan buka IDE tersebut lalu import project spring boot, berikut adalah struktur project jika dilihat dari IDE tersebut.

Screen Shot 2017-01-12 at 10.03.00 PM.png

Langkah Pertama silahkan Buat Struktur aplikasi seperti berikut.

Screen Shot 2017-01-13 at 11.31.01 AM.png

Silahkan buka class Barang yang ada di package domain. Kemudian ubah codingannya menjadi seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.domain

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.mongodb.core.mapping.Field

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:13 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.domain
 * @File Barang
 *
 */
@Document(collection = "tb_barang")
class Barang implements Serializable {

    @Id
    @Field(value = "id_barang")
    String idBarang

    @Field(value = "nama_barang")
    String namaBarang

    @Field(value = "jenis_barang")
    JenisBarang jenisBarang

    @Field(value = "tanggal_kadaluarsa")
    Date tanggalKadaluarsa

    @Field(value = "harga_satuan_barang")
    BigDecimal hargaSatuanBarang

    @Field(value = "jumlah_barang_tersedia")
    Integer jumlahBarangTersedia

}

Dari codingan diatas dapat kita lihat bahwa penulisan sintak java dan groovy sangat lah mirip, dimana terdapat perbedaan yaitu groovy tidak mengharuskan developer untuk menulis titik koma (;). Pada artikel ini, penulis menggunakan database mongodb maka pada saat mendeklarasikan domain / class pojo kita menggunakan annotation @Document dimana annotation tersebut mewakili dari collection yang ada di database mongodb. Untuk mendeklarasikan jenis barang, kita menggunakan enum class, silahkan buat sebuah enum class dengan nama JenisKelamin, Kemudian isikan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.domain

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:15 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.domain
 * @File JenisBarang
 *
 */
enum JenisBarang {
    gas, padat, cair
}

Setelah selesai, tahap selanjutnya silahkan buka class Penjualan untuk aksi transaksi, kemudian isikan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.domain

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.mongodb.core.mapping.Field

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:17 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.domain
 * @File Penjualan
 *
 */
@Document(collection = "tb_penjualan")
class Penjualan implements Serializable {

    @Id
    @Field(value = "id_penjualan")
    String idPenjualan

    @Field(value = "tanggal_transaksi")
    Date tanggalTransaksi

    @Field(value = "nama_pembeli")
    String namaPembeli

    @Field(value = "total_harga")
    BigDecimal totalHarga

}

Sama seperti sebelumnya, class ini berisi tentang domain / class pojo. Kemudian buka class PenjualanDetail lalu masukkan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.domain

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.DBRef
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.mongodb.core.mapping.Field

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:20 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.domain
 * @File PenjualanDetail
 *
 */
@Document(collection = "tb_penjualan_detail")
class PenjualanDetail implements Serializable {

    @Id
    @Field(value = "id_penjualan_detail")
    String idPenjualanDetail

    @Field(value = "jumlah_barang")
    Integer jumlahBarang

    @Field(value = "total_harga_per_barang")
    BigDecimal totalHargaPerBarang

    @DBRef(lazy = true)
    Penjualan penjualan

    @DBRef(lazy = true)
    Barang barang

}

Pada domain PenjualanDetail terdapat sedikit tambahkan yaitu annotation DBRef dimana annotation ini berfungsi sebagai relasi antara collection. Terdapat 1 Penjualan dengan banyak Penjualan Detail dan begitu pula dengan barang, sehingga relasi ini menghasilkan relasi one to many dari penjualan ke penjualan detail dan dari barang ke penjualan detail.

Langkah selanjutnya silahkan buka file BarangRepository, kemudian isikan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.repository

import com.rizki.mufrizal.belajar.spring.boot.domain.Barang
import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.data.rest.core.annotation.Description
import org.springframework.data.rest.core.annotation.RepositoryRestResource

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:23 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.repository
 * @File BarangRepository
 *
 */
@RepositoryRestResource(collectionResourceRel = "barang", path = "barang", collectionResourceDescription = @Description("API Barang"))
interface BarangRepository extends MongoRepository<Barang, String> {

}

class BarangRepository adalah sebuah class interface dimana di dalam class ini kita melakukan extends terhadap class MongoRepository sehingga melalui class ini kita dapat melakukan process create read update dan delete. Spring data mongodb telah menyediakan fungsi paging, sorting dan lain sebagainya, bahkan kita dapat melakukan custom terhadap query yang kita butuhkan. Dikarenkan project ini menggunakan spring data rest maka kita tidak lagi memerlukan membuat controller maupun service, sehingga dari class respository sudah dapat dilakukan proses manipulasi data. Bagaimana kita dapat mengetahui url / end point yang digunakan ? kita dapat mengetahuinya melalui path yang ada di annotation RepositoryRestResource. Untuk end point / url process create update, read dan delete secara otomatis akan dibuatkan berdasarkan method http. Berikut adalah daftar listnya :

Method Http Deksripsi
GET Untuk mengambil data
POST Untuk menyimpan data
PUT Untuk merubah data
DELETE Untuk menghapus data

Selanjutnya silahkan buka class PenjualanRepository kemudian isikan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.repository

import com.rizki.mufrizal.belajar.spring.boot.domain.Penjualan
import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.data.rest.core.annotation.Description
import org.springframework.data.rest.core.annotation.RepositoryRestResource

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:25 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.repository
 * @File PenjualanRepository
 *
 */
@RepositoryRestResource(collectionResourceRel = "penjualan", path = "penjualan", collectionResourceDescription = @Description("API Penjualan"))
interface PenjualanRepository extends MongoRepository<Penjualan, String> {

}

Sama seperti class sebelumnya, selanjutnya silahkan buka class PenjualanDetailRepository kemudian isikan codingan seperti berikut.

package com.rizki.mufrizal.belajar.spring.boot.repository

import com.rizki.mufrizal.belajar.spring.boot.domain.PenjualanDetail
import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.data.rest.core.annotation.Description
import org.springframework.data.rest.core.annotation.RepositoryRestResource
import org.springframework.data.rest.core.annotation.RestResource

/**
 *
 * @Author Rizki Mufrizal <mufrizalrizki@gmail.com>
 * @Web <https://RizkiMufrizal.github.com>
 * @Since 12 January 2017
 * @Time 10:26 PM
 * @Project Belajar-Spring-Boot
 * @Package com.rizki.mufrizal.belajar.spring.boot.repository
 * @File PenjualanDetailRepository
 *
 */
@RepositoryRestResource(collectionResourceRel = "penjualan_detail", path = "penjualan_detail", collectionResourceDescription = @Description("API Penjualan detail"))
interface PenjualanDetailRepository extends MongoRepository<PenjualanDetail, String> {

}

Kemudian tahap terakhir silahkan buka file application.properties yang ada di folder resouces, kemudian isikan codingan berikut.

#konfigurasi mongodb
spring.data.mongodb.database=belajar_spring_boot
spring.data.mongodb.host=127.0.0.1
spring.data.mongodb.port=27017

#konfigurasi HATEOAS
spring.hateoas.use-hal-as-default-json-media-type=true

endpoints.cors.allowed-methods = POST, GET, OPTIONS, DELETE, PUT
endpoints.cors.allowed-origins = '*'
endpoints.cors.exposed-headers = accept, authorization, x-requested-with, content-type
endpoints.cors.max-age = 3600

#konfigurasi jackson
spring.jackson.serialization.indent-output=true

#konfigurasi spring data rest
spring.data.rest.base-path=/api

Setelah selesai, tahap terakhir kita akan menjalankan aplikasi web nya dengan perintah.

mvn clean spring-boot:run

Berikut adalah output ketika dijalankan.

Screen Shot 2017-01-13 at 10.06.11 PM.png

Kemudian kita lakukan testing menggunakan postman, berikut adalah proses menyimpan data untuk barang

Screen Shot 2017-01-13 at 10.10.46 PM.png

berikut adalah proses menyimpan data untuk penjualan

Screen Shot 2017-01-13 at 10.11.27 PM.png

berikut adalah proses menyimpan data untuk penjualan detail

Screen Shot 2017-01-13 at 10.26.38 PM.png

Bagi anda yang ingin melihat source code codingan, silahkan lihat di Belajar Spring Boot. Sekian artikel mengenai Membuat RESTful Web Service Dengan Framework Spring Boot dan terima kasih :)