Java Spring Boot REST API

Merhaba, bu yazıda Spring Boot ile basit bir Rest Api oluşturacağız. Daha sonra oluşturduğumuz servisi bir Flutter uygulamasında kullanacağız. Hali hazırda java ve spring boot ortamının kurulu olduğunu varsayarak devam edeceğim. İlk olarak, Spring initializr kullanarak ya da VSCode Spring initializr eklentisini kullanarak bir spring boot projesi oluşturalım. Aşağıda proje ayrıntılarını görebilirsiniz:

Şimdi kodlamaya geçebiliriz. Benim proje dizinim aşağıdaki gibi, siz de classları bu şekilde oluşturabilirsiniz:

Kullanacağımız json dosyasının formatına göre bir model sınıfı oluşturacağız. Json formatımız şu şekilde:

Bu formata göre oluşturduğumuz Country sınıfı ise aşağıdaki şekilde olacak:

public class Country implements Comparable<Country>{
   final String id;
   final String name;
   final String nativeName;
   final int phoneCode;
   final String continent;
   final String capital;
   final String currency;
   final List<String> languages;
   final List<Byte> flag;
 
   public Country(String id, String name,String nativeName, int phoneCode, String continent, String capital,String currency, List<String> languages,List<Byte> flag) {
       this.id = id;
       this.name = name;
       this.nativeName = nativeName;
       this.phoneCode = phoneCode;
       this.continent = continent;
       this.capital = capital;
       this.currency = currency;
       this.languages = languages;
       this.flag = flag;
   }
 
   @Override
   public int compareTo(Country o) {
       int phoneCode = ((Country)o).phoneCode;
       //Ascending order
       return this.phoneCode - phoneCode;
   }
}

Bu sınıftan türetilen nesneleri daha sonra telefon kodlarına göre sıralamam gerektiği için Comparable interface ini implement ettim. Bu kısım zorunlu değil.

Şimdi Controller tarafını kodlayalım, 

@RestController
public class CountryController {
 
   @GetMapping("countries")
   public List<Country> countries(
       @RequestParam(value = "countryCode",defaultValue = "") String countryCode) throws IOException {
 
       List<Country> countries = new ArrayList<>();
 
       //parse json to country models and add them to list
       File jsonFile = new File("src/asset/countries.json");
       Map<String,Map<String,Object>> result =
               new ObjectMapper().readValue(jsonFile, HashMap.class);

countries metoduna parametre olarak geçtiğimiz @RequestParam ile servise parametreye göre data isteği atabileceğiz. Yani bizim örneğimizde url ye parametre olarak vereceğimiz ülke koduna sahip ülkenin verisi dönecek. Eğer herhangi bir parametre geçmezsek default olarak bütün ülkeler dönecek. Özelleştirilmiş istek url si aşağıdaki şekilde olacak:

localhost:8080/?countryCode=TR

Devam edelim, ilk etapta local de tuttuğumuz json dosyasının formatını biraz değiştirip server a göndereceğim için localdeki json u okuyup model sınıfına parse ederek bir listeye attım. 

  //all country codes.
  Set<String> keySet = result.keySet();
  //if there is requested param, key set will be updated.
  if(!countryCode.isEmpty()){
     keySet = new HashSet<>();
     keySet.add(countryCode);
  }

Yukarıdaki kod parçasıyla localden okuduğumuz json datasını map e çevirdik ve keySet() metodu ile bütün id leri bir Set içerisine attık. (Bu set ile daha sonra bir döngü içerisinde bu id lere karşılık gelen değerleri alacağız ve Country nesnelerimizi oluşturacağız. ) Daha sonra istek gönderilirken parametre olarak bir id geçilmiş mi diye kontrol ediyoruz. Eğer özel bir ülke kodu parametre verildi ise Set imizi güncelleyerek sadece bu id den ibaret yapıyoruz. Devam edelim.

 //Stream for flag data
 InputStream in = null;
 
 for (String id : keySet) {
      in = null;
      Map<String,Object> m = result.get(id);
      String name = m.get("name").toString();
      String nativeName = m.get("native").toString();
      int phone;
      try{
          phone = Integer.parseInt(m.get("phone").toString());
      }
      catch(NumberFormatException e){
          phone = -999;
      }
      String continent = m.get("continent").toString();
      String capital = m.get("capital").toString();
      String currency = m.get("currency").toString();
      List<String> languages = (ArrayList<String>)m.get("languages");
      in = new BufferedInputStream(new FileInputStream("src/asset/country_flags/"+   id.toLowerCase(Locale.ENGLISH) + ".svg"));
      Country c = new Country(id,name,nativeName,phone,continent,capital,currency,languages,toList(in.readAllBytes()));
      countries.add(c);
  }

Yukarıda bir InputStream oluşturdum, bu stream ile ülkelerin bayraklar görsellerini byte olarak server a göndereceğim json a gömeceğim. 

Bahsettiğim döngüyü oluşturduk ve Country nesnelerini üreterek listemize ekledik. Şimdi bu listeyi döndüreceğiz ve @GetMapping anotasyonu ile işaretlediğimi metod bizim için server ı oluşturacak.

       Collections.sort(countries);
       in.close();
       return countries;
  }

Kendi yazdığımız toList(byte[]) metodumuz da aşağıdadır:

private List<Byte> toList(byte [] bytesArr){
       Byte[] b = IntStream.range(0, bytesArr.length)
                           .mapToObj(i -> bytesArr[i])
                           .toArray(Byte[]::new);
       return Arrays.asList(b);
 }

İşlemimiz tamam, şimdi projeyi çalıştıralım ve localhost:8080/countries url sine bir sorgu atalım. Tarayıcıdan da atabilirsiniz fakat gelen json datası çok anlaşılır olmayacaktır. Ben Postman kullanıyorum. Postman ekranını aşağıya ekliyorum:

Ülke koduna özel olarak attığımız isteğin sonucu da aşağıdadır:

Bu tasarladığımız Rest Api yi bir sonraki yazımızda Flutter Dart ortamında kullanmayı göreceğiz. Projenin tamamına github hesabımdan erişebilirsiniz: https://github.com/aedemirsen/CountryInfoRestApi

İyi Çalışmalar.

Leave a Reply

Your email address will not be published. Required fields are marked *