Data

JavaScript ve HTTP Request

Güncelleme:
Şimdiye değin, routing yazı akışı bağlamında Vue Routing ile temel örnekler hazırlamış ve bu örneklerde de Axios yeteneklerinden faydalanmıştım. Elbette Axios JavaScript ile gerçekleştirebileceğimiz HTTP ...
GÖRSEL

Şimdiye değin, routing yazı akışı bağlamında Vue Routing ile temel örnekler hazırlamış ve bu örneklerde de Axios yeteneklerinden faydalanmıştım. Elbette Axios JavaScript ile gerçekleştirebileceğimiz HTTP request’ler için tek alternatif değil. Hatta Ajax ile daha da geçmişe gidebiliriz. Peki, başka hangi farklı biçimleri tercih edebiliriz. Bu yazıda, fikir olması aısından işte bu farklı alternatiflere değinmek istiyorum.

JavaScript İle HTTP Request Kullanımı

JavaScript aracılığıyla farklı modül ve methodlar kullanılarak kolaylıkla HTTP istekleri (request) gerçekleştir; sunucu tarafındaki bir kaynaktan veri alıp gönderebiliriz. Peki, nasıl?

Örnek REST API işlemleri gerçekleştirebilmek amacıyla kullanılabilecek bazı servislerden API Testing başlıklı yazıda daha önce bahsetmiştim. Yine bu yazıda yer alan SWAPI (The Star Wars API) ile devam edebiliriz. Diğer yandan, sadece bilgi olarak eklemekte fayda var; örnek sürecinde Bulma CSS için şu şablonu kullanacağım. Ancak, verileri console üzerinden görüntüleyeceğimiz için UI işlemleri şimdilik bir önem teşkil etmemekte.

<!DOCTYPE html>
<html>
 
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Hello Bulma!</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css" />
  <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
</head>
 
<body>
  <section class="section">
    <div class="container">
      <h1 class="title">
        HTTP Request Examples
      </h1>
      <article id="getData" class="message">
        <div class="message-body"></div>
      </article>
      <div id="doSomething" class="button is-small is-link">Get the data</div>
    </div>
  </section>
  <script>
    // HTTP Request
  </script>
</body>
</html>

İlgili açıklamaları ayrıca bölümler içerisinde görebilirsiniz. O halde Ajax ile başlayalım.

Ajax İle HTTP Request Kullanımı

Ajax asenkron HTTP istekleri (asynchronous HTTP request) gerçekleştirmek için kullanılabilecek geleneksel bir yöntem olarak ifade edilebilir. GET ve POST metodlarını kullanarak veri alabilir ve gönderebiliriz. Bu işlem için XMLHttpRequest (XHR) kullanırız. Daha detaylı bilgi için MDN web docs > XMLHttpRequest.responseType sayfasını inceleyebilirsiniz.

    const element = document.getElementById("getData");
    const xhr = new XMLHttpRequest();
    xhr.open("GET", "https://swapi.co/api/people/1");
    xhr.send();
    xhr.onreadystatechange = function () {
      if (this.readyState === 4) {
        if ((this.status == 200) && (this.status < 300)) {
          console.log(this.responseText)
        }
      }
    }
<script>// HTTP Request</script> alanını yukarıdaki şekile güncellememizin ardından console’da şu dönüşü alırız.
{
    "name": "Luke Skywalker",
    "height": "172",
    "mass": "77",
    "hair_color": "blond",
    "skin_color": "fair",
    "eye_color": "blue",
    "birth_year": "19BBY",
    "gender": "male",
    "homeworld": "https://swapi.co/api/planets/1/",
    "films": [
        "https://swapi.co/api/films/2/",
        "https://swapi.co/api/films/6/",
        "https://swapi.co/api/films/3/",
        "https://swapi.co/api/films/1/",
        "https://swapi.co/api/films/7/"
    ],
    "species": [
        "https://swapi.co/api/species/1/"
    ],
    "vehicles": [
        "https://swapi.co/api/vehicles/14/",
        "https://swapi.co/api/vehicles/30/"
    ],
    "starships": [
        "https://swapi.co/api/starships/12/",
        "https://swapi.co/api/starships/22/"
    ],
    "created": "2014-12-09T13:50:51.644000Z",
    "edited": "2014-12-20T21:17:56.891000Z",
    "url": "https://swapi.co/api/people/1/"
}

Ajax ile bir HTTP call gerçekleştirebilmek için bir XMLHttpRequest() metodu başlatılması, URL endpoint ve HTTP metodu (GET veya POST) belirtilmesi gerekir. Yukarıdaki örnekte GET metodunu kullandığımızı görebilirsiniz. Son olarak, HTTP metodu ve URL endpoint’i birbirine bağlamak için open() metodunu kullanırız ve işlemi tamamlamak için send() yöntemini çağırırız.

XMLHTTPRequest.onreadystatechange ile birlikte değişen durumu yakalar ve işlemler gerçekleştiririz. Yukarıdaki örnekte isteğin başarılı olması durumunda (readyState === 4) GET ile edindiğimiz veriyi ID’si belirtilen element’e ekleriz.

jQuery İle HTTP Request Kullanımı

JavaScript Ajax dışında, bir jQuery metodu olan $.Ajax gibi alternatif ve güçlü yöntemlere de sahiptir. Elbette bu işlem için jQuery kütüphanesinin de çalışma sürecine dahil edilmesi gerekir. Bu nedenle, yukarıdaki örneğe aşağıdaki satırı eklememiz gerekir.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

$.ajax metodu pek çok parametreye sahiptir. Bunlardan bazıları opsiyonel iken bir kaçının tanımlanması zorunludur. Ek olarak, $.ajax 2 callback’e sahiptir; alınan cevaba (response) göre success ve error ile işlemleri gerçekleştiririz.

    $(document).ready(function () {
      const endPoint = "https://swapi.co/api/people/1";
      $('#doSomething').click(function () {
        $.ajax({
          url: endPoint,
          type: "GET", #ya da POST
          success: function (result) {
            console.log(result);
          },
          error: function (error) {
            console.log(`Error ${error}`);
          }
        });
      });
    });

$.ajax ile metodları type olarak belirtebileceğimiz gibi doğrudan metod olarak da işleme alabiliriz.

$.get metodu

$.get metodu HTTP GET isteklerini (request) yerine getirmek amacıyla kullanılır ve iki parametre alır; endpoint ve callback fonksiyonu.

    $(document).ready(function () {
      const endPoint = "https://swapi.co/api/people/1";
      $('#doSomething').click(function () {
        $.get(endPoint, function (data, status) {
          if (status == "success") {
            console.log(data);
            $('.message-body').append(JSON.stringify(data));
          } else {
            console.log(`Error ${status}`);
          }
        });
      });
    });

$.post metodu

Şimdi de, jQuery kütüphanesi sayesinde kullanabildiğimiz $.ajax POST işlemimini $.post metoduna bir bakalım. $.post metodunu sunucuya veri göndermek (post) için kullanırız. 3 parametre alır; URL, data (gönderilecek veri) ve callback fonksiyonu.

405 Error: Method POST not allowed

POST metodunu kullanabilmek için REST API servisini değiştirmemiz gerekir. Çünkü SWAPI POST metodunu desteklememektedir. Bu tür durumlarda, POST isteğinde bulunduğumuzda 405 Status Code ile Method 'POST' not allowed dönüşünü alırız. O halde POST metodu için REQ | RES servisinden faydalanalım.

    $(document).ready(function () {
      const endPoint = "https://reqres.in/api/users";
      const data = {
        name: "Zorg",
        job: "Handyman"
      };
      $('#doSomething').click(function () {
        $.post(endPoint, data, function (data, status) {
          if (status == "success") {
            console.log(data);
            $('.message-body').append(JSON.stringify(data));
          } else {
            console.log(`Error ${status}`);
          }
        });
      });
    });

Yukarıdaki işlemin başarıyla gerçekleşmesi durumunda (status eğer success ise) ayrıca şu dönüşü alırız.

{
    "name": "Zorg",
    "job": "Handyman",
    "id": "772",
    "createdAt": "2019-08-13T06:32:41.370Z"
}

$.ajax, $.get ve $.post dışında ayrıca $.getJSON metodunu da kullanabiliriz. Önceki metodlarda JSON, HTML, XML, TXT, jsonp data tiplerinde işlem yapabilirken $.getJSON bize sadece JSON formatında veri edinimi sağlar. 2 parametre alır; endpoint ve callback fonksiyonu.

    $(document).ready(function () {
      const endPoint = "https://reqres.in/api/users";
      $('#doSomething').click(function () {
        $.getJSON(endPoint, function (result) {
          if (result.data.length > 0) {
            console.log(result.data);
            $('.message-body').append(JSON.stringify(result.data));
          } else {
            console.log(`Error ${result}`);
          }
        });
      });
    });

Fetch

fetch(), XMLHttpRequest (XHR) ‘ye benzer şekilde istekler (request) gerçekleştirebilmemizi sağlar. Ana farklılık, FETCH API’in Promise kullanmasıdır. Bu sayede, daha basit ve temiz bir API kullanımı mümkün hale gelmekte, callback karmaşasından ve diğer kompleks süreçlere maruz kalmayız.

Fetch parametre olarak sadece endpoint’e ihtiyaç duyar.

    const endPoint = "https://reqres.in/api/users";
    fetch(endPoint)
      .then(data => {
        return data.json()
      })
      .then(res => {
        console.log(res)
      });

Yine önceki örnek akışı üzerinden devam edelim ve butonun tıklanmasının ardından verilerin gelmesini sağlayalım.

    $(document).ready(function () {
      const endPoint = "https://reqres.in/api/users";
      $('#doSomething').click(function () {
        fetch(endPoint)
          .then(data => {
            return data.json()
          })
          .then(res => {
            console.log(res)
            $('.message-body').append(JSON.stringify(res.data));
          })
      });
    });

Fetch’in opsiyonel olarak alabileceği parametreler ise method, headers, credentials, mode, cache, redirect, referrer ve body.

fetch(endPoint, {
    method: 'post',
    headers: {
      "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
    },
    body: 'foo=bar&lorem=ipsum'
  })
  .then(json)
  .then(function (data) {
    console.log('Request succeeded with JSON response', data);
  })
  .catch(function (error) {
    console.log('Request failed', error);
  });

Daha kapsamlı bir örnek olarak:

    postData('https://reqres.in/api/users', {
        name: "Zorg",
        job: "Handyman"
      })
      .then(data => console.log(JSON.stringify(data))) // JSON-string from `response.json()` call
      .catch(error => console.error(error));
 
    function postData(url = '', data = {}) {
      // Default options are marked with *
      return fetch(url, {
          method: 'POST', // *GET, POST, PUT, DELETE, etc.
          mode: 'cors', // no-cors, cors, *same-origin
          cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
          credentials: 'same-origin', // include, *same-origin, omit
          headers: {
            'Content-Type': 'application/json',
            // 'Content-Type': 'application/x-www-form-urlencoded',
          },
          redirect: 'follow', // manual, *follow, error
          referrer: 'no-referrer', // no-referrer, *client
          body: JSON.stringify(data), // body data type must match "Content-Type" header
        })
        .then(response => response.json()); // parses JSON response into native JavaScript objects 
    }

Axios

Benim de örneklerde sıklıkla kullandığım, browser ve node.js ile de çalışabilen popüler bir diğer promise-based HTTP client. Fetch ile pek çok biçimde benzeşmesine karşın Axios HTTP metodları için daha pratik ve kapsamlı çözümler sağlamaktadır. Teknik detaylar hakkında İleri Okumalar başlığında yer alan içeriklere göz atabilirsiniz.

Axios’u bir paket yöneticisi (yarn, npm vb.)

npm install axios
#ya da
yarn add axios

ya da doğrudan bir CDN bağlantısı ile kullanabiliriz.

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

Hemen örneğimize GET metodu ile başlayalım.

    const endPoint = "https://reqres.in/api/users";
    axios.get(endPoint)
      .then(data => console.log(data))
      .catch(err => console.log(err))

Örneği POST metoduyla yineleyelim.

    const endPoint = "https://reqres.in/api/users";
    const params = {
      name: "Zorg",
      job: "Handyman"
    };
    axios({
        method: "post",
        url: endPoint,
        data: {
          params
        }
      })
      .then(data => console.log(data))
      .catch(err => console.log(err))

Sonuç olarak, pek çok alternatif kullanım çerçevesinde işlemler gerçekleştirmeye çalıştım. Ancak, VUE-Resource, Request ve Supertest gibi değinmediğim de çeşitli alternatifler mevcut. Fetch’in harici bir kaynak gereksinimi olmaksızın kullanımı bir avantaj sağlamakta iken, Axios çok daha detaylı işlemler sağalayabilmekte. Dolayısıyla, gereksimimlere göre karar vermek daha doğru olacaktır. İlerleyen yazılarda önceliğim Axios olsa da kimi durumlarda Fetch’e de denk gelinmesi olası.

İleri Okumalar

  1. XMLHttpRequest.responseType, @MDN web docs
  2. XMLHttpRequest.readyState, @MDN web docs
  3. JSON.stringify(), @MDN web docs
  4. JSON.parse(), @MDN web docs
  5. Introduction to fetch(), @Google Developers
  6. Fetch API, @MDN web docs
  7. Using Fetch, @MDN web docs
  8. What is difference between Axios and Fetch?
  9. HTTP Requests Compared: Why Axios Is Better Than Node-Fetch (Automatic Transformations, More Secure, Can Handle Errors Better, Interceptor Support, And More Browser Friendly)
  10. Comparing JavaScript HTTP Requests Libraries for 2019

Kaynakça

  1. Fetch Standard
  2. Here are the most popular ways to make an HTTP request in JavaScript
  3. AJAX Requests in Vue.js: Axios vs vue-resource vs fetch
  4. What is the difference between Ajax request and XHR request?
Ceyhun Enki Aksan

Kullanıcı Davranışları Analizi (User Behavior Analysis) ve Kullanıcı Deneyim Tasarımı (UX Design) üzerine çalışmalar yürütmekte, bu süreçte edindiğim teknik ve pratik bilgileri fayda sağlamak motivasyonuyla (afaik / as far as i know) paylaşmaktayım.

HABERDAR OL

Yeni eklenen projeler, eğitimler, içerikler ve yayınlanan videolar e-posta adresine gelsin.