JavaScript ve HTTP Request

Ş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.

AA

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 etmemekte1.

<!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 metotlarını kullanarak veri alabilir ve gönderebiliriz2 3. Bu işlem için XMLHttpRequest (XHR) kullanırız. Daha detaylı bilgi için MDN web docs > XMLHttpRequest.responseType4 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() metotu başlatılması, URL endpoint ve HTTP metotu (GET veya POST) belirtilmesi gerekir. Yukarıdaki örnekte GET metotunu kullandığımızı görebilirsiniz. Son olarak, HTTP metotu ve URL endpoint'i birbirine bağlamak için open() metotunu 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 metotu 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 gerekir5. 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 metotu 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 metotları type olarak belirtebileceğimiz gibi doğrudan metot olarak da işleme alabiliriz.

$.get metotu

$.get metotu 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 metotu

Şimdi de, jQuery kütüphanesi sayesinde kullanabildiğimiz $.ajax POST işlemimini $.post metotuna bir bakalım. $.post metotunu 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 metotunu kullanabilmek için REST API servisini değiştirmemiz gerekir. Çünkü SWAPI POST metotunu 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 metotu 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 metotunu da kullanabiliriz. Önceki metotlarda 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ız6.

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 metotları 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

Doğrudan bir CDN bağlantısı ile kullanabiliriz.

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

Hemen örneğimize GET metotu 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 metotuyla 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