Retrofit 2.x ile REST Api Yönetimi #3

Can Uzun
6 min readJun 3, 2017

Buraya laps geldi isen önce #1 ve #2 kısmını tavsiye ederim. Api yazdık, CRUD Web uygulaması oluşturduk. 🤓

Retrofit 2.x ile REST Api Yönetimi #1

Retrofit 2.x ile REST Api Yönetimi #2

Bende Api var, CRUD uygulamam var birde. Bu Api’ye de bir URL ile erişebiliyorum. 😱⁠⁠⁠⁠ Aman Tanrım! Çok hızlı düşünmeni istemem ama fikirlere bak! Bu Api’yi Server’a atsan, yani senin localhost’unda değilde, www.alanadi.com/api adresinde çalışsa, wow, en basitinden Evernote yazarsın bence. Çünkü bu sana ne sağlıyor.

Veriye lokasyon bağımsız erişebilmeni, değiştirebilmeni… Nasıl? GET, POST metodları ile. Yani sen yapabiliyorsan makas ile POST istemi kullanarak Controller’ına uygun objeyi gönder, veritabanına yazar.

Biraz Api’yi açıklamak istiyorum sana; fakat bu arada kavramların ezber bilgisi ile öğrenilmesine çok sıcak bakan birisi değilimdir. Api’nin açılımını vermeyeceğim mesela, başta REST’in verdim, merak etme diye. Fakat kullanımını bil, ne işe yaradığını yeter. Bunlar onunla neler yapabileceğini hayal etmeni sağlayacak kavramlar. İsmi… Meh…

Api, yazdığın uygulamanın verilerinin istediğin kısmını ya da fonksiyonlarının istediğin kısmını dışarıya aktarmak için kullandığın bir şey. Güvenli değil gibi geliyor böyle ama Token vererek, Session Control yaparak ya da bilmiyorum başka şekillerde Api’ni koruma yöntemleri mutlaka vardır.

Bu kadar uzattığımız yeter, hadi basit bir arayüz ile Android uygulaması yazalım. Burada umarım işini zorlaştırmaz ama bence sana bir kıyak yapacağım, uygulamaya dışarından tasarım kütüphaneleri ekleyerek oluşturacağım, o yüzden bu kısım biraz uzasa da işine yarayacak bilgiler içerecek, emin ol.

İhtiyaçlar listesine Android Studio’da eklendi bu arada, onu indirip kurmalısın. Birde Genymotion’un olsun, uygulamanı test etmek için.

Adım 3.1 — Android Projesi Oluşturma

Menüden File > New > New Project seçeneği ile yeni bir proje oluşturalım. Projemize bir isim verek diğer adıma geçelim.

Hizmet sunacağımız en düşük Android sürümünü seçelim.

Sonrasında boş bir Activity oluşturalım.

Son olarakta bu Activity’mize bir isim verelim.

Adım 3.2 — Çalışma Düzenimizi Oluşturma

Boş bir proje oluştu bizim için, ne kadar düzenli hareket edersekte o kadar rahat ve kolay çalışırız.

Soldaki Project kısmından app>java altında bulunan yarattığınız Activity’nin bulunduğu klasöre sağ tıklayın ve

New>Package seçeneği ile 2 adet paket oluşturun, isimleri ise “api” ve “ui” olsun.

Ardından “api” paketi içerisine “model” ve “service” isimleri ile 2 paket daha oluşturun. MainActivity’nizide “ui” içerisine taşıyın. Son durum şu yani, her şey ileride rahat etmek için bu arada, istersen yapmayabilirsin.

Adım 3.3 — Projemize Gerekli Kütüphaneleri Ekleme

Kütüphane?

Bazı insanlar var çok güzel biliyor musun? :) Bir sürü kişi bu arada, farklı farklı. Senin işini kolaylaştıracak ya da güzelleştirecek bir sürü kod parçaları yazmışlar ve bunları nasıl kullanabileceğini de çoğu açıklamış. Bu kod parçalarına biz kütüphane diyoruz. Bunu Google’da yazmış olabilir, Ahmet’te, güveniyorsan, işine yarıyorsa, işini güzelleştiriyor ya da kolaylaştırıyorsa projene ekler kullanırsın. Github’ta bir sürü var.

Soldaki Project menümüzden Gradle Scripts > build.gradle (Module: app) olana çift tıklıyoruz. İşte tüm bu kütüphanelerin nerede olduğunu burada belirteceğiz. -dependencies kısmında.

compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4'
compile 'com.squareup.retrofit2:retrofit:2.2.0' //A
compile 'com.squareup.retrofit2:converter-gson:2.2.0' //B
compile 'com.weiwangcn.betterspinner:library-material:1.1.0' //C
compile 'com.github.clans:fab:1.6.2' //D
compile 'com.android.support:design:25.3.1' //E
testCompile 'junit:junit:4.12'

Kütüphanelerin yanına A,B,C şeklinde belirttim, hangisinin bizim için ne işe yaradığını bölümlerde bahsederek anlatacağım. Şimdi anlatıp kafa şişirmek istemem :D Bu arada bunları ekleyince Android Studio üstten uyarı verir “Sync Now” a basarak bu kütüphaneleri projenize kaydetmiş olursunuz.

Bu kütüphanelerin hemen ne işe yaradığını merak ediyorsanızda tırnak işaretleri içerisinde “com” ile başlayan kısmı komple kopyalayıp Google’a sorun :) Belki yeni versiyonu çıkmıştır, sonundaki versiyon numarasını değiştirerek yenisini eklersiniz :)

Adım 3.4 —Arayüz?

Hemen küçük bir özet, “ui” içindeki MainActivity bir java class’ıdır. Burada beyin kodlarını, çalışan aksamı yazarsın, farklı yöntemleride vardır ama ilk düzen böyle. Birde bu yazdığın kodların görsel olarak girdi, çıktı aldığın bir arayüzü vardır. Basit düşünelim iki sayıyı çarpacak bir program yazıyorsun, 2 sayıyı alıp, sonucu yazacağın bir arayüz olmalı, bu çarpmayıda Activity’nde yapıyorsun. Activity’n ile ilişkili arayüz res>layout içerisindedir, eğer o Activity’i hangi arayüz ile ilişkilendirdiğini bilmiyor isen Activity kodlarında bu vardır. Aşağıda “activity_main” miş bizim için. Umarım uzatmıyorumdur :)

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

activity_main.xml dosyana çift tıklarsan Android Studio sana arayüz inşaa edebilmen için bir yapı sunar. Altta Design/Text sekmeleri vardır, tasarımı XML şeklinde tutar, bu XML kodları Text kısmındadır. Bazı ekipmanları buradan düzenleyip ekleyip kaldıracağız, o yüzden burayıda bilmen önemli. Bunlar tasarım için bu arada.

Adım 3.5 — Arayüz Tasarımı

Android uygulamamızın amacı Api’de bulunan veriyi çekmek ya da Api yardımıyla veritabanına veri göndermek olacağı için, veritabanımızdaki verilere ait birer Edittext ve verileri listeleyebileceğimiz bir ListView ile ekle, veriyi çek butonlarına ihtiyacımız var.

C,D,E kütüphanelerini tasarım için kullandık.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:fab="http://schemas.android.com/apk/res-auto"
tools:context="com.can.anyma.apimanagementapp.ui.MainActivity"
android:orientation="vertical"
android:weightSum="1">


<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:id="@+id/yetkili"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Yetkili" />
</android.support.design.widget.TextInputLayout>

<com.weiwangcn.betterspinner.library.material.MaterialBetterSpinner
android:id="@+id/bolge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Bölge Seçiniz"
android:textColorHint="#05ab9a"
app:met_floatingLabel="normal" />

<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:id="@+id/aciklama"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Açıklama" />
</android.support.design.widget.TextInputLayout>

<ListView
android:id="@+id/veri_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</LinearLayout>


<com.github.clans.fab.FloatingActionMenu
android:id="@+id/material_design_android_floating_action_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="11dp"
android:layout_marginLeft="11dp"
android:layout_marginRight="11dp"
fab:menu_animationDelayPerItem="55"
fab:menu_backgroundColor="@android:color/transparent"
fab:menu_buttonSpacing="0dp"
fab:menu_colorNormal="#1E88E5"
fab:menu_colorPressed="#1565C0"
fab:menu_colorRipple="#99d4d4d4"
fab:menu_fab_size="normal"
fab:menu_icon="@drawable/fab_add"
fab:menu_labels_colorNormal="@android:color/background_light"
fab:menu_labels_colorPressed="#444"
fab:menu_labels_colorRipple="#66efecec"
fab:menu_labels_cornerRadius="3dp"
fab:menu_labels_ellipsize="none"
fab:menu_labels_hideAnimation="@anim/fab_slide_out_to_right"
fab:menu_labels_margin="0dp"
fab:menu_labels_maxLines="-1"
fab:menu_labels_padding="8dp"
fab:menu_labels_position="left"
fab:menu_labels_showAnimation="@anim/fab_slide_in_from_right"
fab:menu_labels_showShadow="true"
fab:menu_labels_singleLine="false"
fab:menu_labels_textColor="#212121"
fab:menu_labels_textSize="15sp"
fab:menu_openDirection="up"
fab:menu_shadowRadius="1dp"
fab:menu_shadowXOffset="1dp"
fab:menu_shadowYOffset="1dp"
fab:menu_showShadow="true">

<com.github.clans.fab.FloatingActionButton
android:id="@+id/fab_menu_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_check_white_24dp"
fab:fab_colorNormal="#64B5F6"
fab:fab_colorPressed="#BBDEFB"
fab:fab_label="Verileri Çek"
fab:fab_size="mini" />


<com.github.clans.fab.FloatingActionButton
android:id="@+id/fab_menu_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_lead_pencil_white_18dp"
fab:fab_colorNormal="#123d60"
fab:fab_colorPressed="#64B5F6"
fab:fab_label="Veri Ekle"
fab:fab_size="mini" />
</com.github.clans.fab.FloatingActionMenu>

</RelativeLayout>

Basit bir arayüz oluşturduk. Bunu tasarım kısmından sürükle bırak ile yapabileceğiniz gibi üstteki kodu text kısmına yapıştırarakta elde edebilirsiniz. Fakat res>drawable klasörüne .png resmi şeklinde koyduğum ikonları eklemelisiniz ya da siz farklı ikonlar kullanabilirsiniz. Id’lerimizide verdiysek kullandığımız ögeleri kodlamaya geçebiliriz.

Adım 3.6 — Activity ve Arayüz Arasında Verileri Ayarlama

MainActivy classımıza geri dönelim. Aşağıdaki kod sayesinde tüm ögelerimizi kullanıma hazır hale getirdik ve spinner’ımızın içerisine 4 şehir gönderdik manuel olarak.

package com.can.anyma.apimanagementapp.ui;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;

import com.can.anyma.apimanagementapp.R;
import com.github.clans.fab.FloatingActionButton;
import com.weiwangcn.betterspinner.library.material.MaterialBetterSpinner;

public class MainActivity extends AppCompatActivity {

String[] SPINNERLIST = {"Ankara", "Eskişehir", "İstanbul", "İzmir"};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

final EditText yetkili = (EditText) findViewById(R.id.yetkili);
final EditText aciklama = (EditText) findViewById(R.id.aciklama);
ListView veri_list = (ListView) findViewById(R.id.veri_list);

ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line, SPINNERLIST);
final MaterialBetterSpinner bolge = (MaterialBetterSpinner)findViewById(R.id.bolge);
bolge.setAdapter(arrayAdapter);


FloatingActionButton fab_menu_1 = (FloatingActionButton) findViewById(R.id.material_design_floating_action_menu_item1);
FloatingActionButton fab_menu_2 = (FloatingActionButton) findViewById(R.id.material_design_floating_action_menu_item2);

fab_menu_1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {

}
});
fab_menu_2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {

}
});
}
}

Adım 3.7 — Model Sınıfı Oluşturma

api>model klasörümüze sağ tıklayarak yeni bir class yaratalım. Senaryomuz gereği bu classı “Sorun” olarak adlandırdım ve aşağıdaki gibi gerekli ögeleri yapılandırdım.

package com.can.anyma.apimanagementapp.api.model;

/**
* Created by anyma on 14.05.2017.
*/

public class Sorun {
private Integer id;
private String yetkili;
private String bolge;
private String aciklama;

public Sorun(String yetkili, String bolge, String aciklama) {
this.yetkili = yetkili;
this.bolge = bolge;
this.aciklama = aciklama;
}

public Integer getId() {
return id;
}
}

Adım 3.8 — Gerekli İzinleri Tanımlama

Bizim Api’ye uygulamamız üzerinden erişebilmemiz için, uygulama internet bağlantısına ihtiyaç duyacaktır, bunu app>manifests>AndroidManifest.xml içerisinde gerekli yerde belirtiyoruz.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

Şimdi uygulamamızın boş yapısı Retrofit 2.x ile veri göndermek/almak için hazır. Diğer yazıda Retrofit 2.x ile Api’ye bağlanıp, nasıl veri transferi yapacağımızı anlatacağım.

Android kısmını tasarımdan dolayı biraz uzatmış olabilirim fakat elimden geldiğince tane tane anlatmaya çalıştım ki her şey anlaşılır bir şekilde ilerlesin. Ama sen yinede sorun yaşıyorsan web sitem üzerinden bana ulaşabilirsin :)

www.anymaa.com

--

--

Can Uzun

Product Designer | UX & UI Designer | Head of Design | Design Lead | Web3 Product Designer — Founder at Engcode — www.engcode.net