Rest-Api Giriş

En basitleştirilmiş tanımıyla API; Bir kod bölümünün başka bir kod bölümüyle iletişime geçmesidir. API'ın en genel tanımı bu olmakla birlikte genel olarak ve bu çalışmamız çerçevesinde web üzerinden çoğunlukla HTTP protokolüne göre çalışan API'lar ifade edilir.

REST sunucu ile istemci arasında iletişimi sağlayan API için kullanılan bir mimari yapı. Bu yapıya uygun API'a REST-API denir.

API Nedir?

Application Programming Interface

Bir uygulamada gerçekleştirmek istediğimiz ek bir işlemi, o işlemi sağlayan başka bir uygulamadan API kullanarak gerçekleştirebiliriz.

Interface

Arka planını bilmediğimiz işlevselliğe ulaşmak için kullanılan kısım.

Application Programming

İki yazılımın iletişimi

API neden kullanılır?

  • API kullanımı bizi ilgili işlemin gerektireceği iş yükünden kurtarır. “API hayatı kolaylaştırır”.
  • API lar özel kullanıcı kitlelerine yönelik hazırlanırlar ve ilgili verileri hızlı bir şekilde oluşturmamızı sağlarlar. ( IMDB API, GitHub API ..)
  • Platform bağımsız çalışırlar. Yazıldığı dil bizi ilgilendirmez.
  • Güncelleme durumunda bizim yapmamız gereken işlemler sınırlıdır.

REST API Nedir?

Representational State Transfer

Bir kaynağa yapılan isteğe karşılık gelen veri transferi. Bu transfer genelde JSON formatında olur.

İsteğin yapıldığı andaki güncel state bilgisi çekilir. Alınan yerdeki veriler güncellendikçe çekilen veri de güncellenir.

REST-API, rest mimarisi prensipleri taşıyan API'dır. Tüm prensipleri karşılıyorsa RESTful API denir.

{JSON} Placeholder API yapılarını testetmek için REST-API örneği sunan bir site.

API yapısı ile alınan JSON formatının tarayıcıda düzgün görünmesi için chrome web mağazasından JSON formatter indirilir.

Rest Prensipleri

  • İstemci-Sunucu (Client - Server)
  • Tek tip arayüz (Uniform Interface)
  • Durumsuzluk (Statelessness)
  • Önbelleklenebilirlik (Cacheable)
  • Katmanlı sistem (Layered System)
  • İsteğe bağlı kod (Code on Demand - Optional)

İstemci-Sunucu (Client - Server)

İstemci isteği gönderen, sunucu da ilgili cevabı veren durumundadır. Birbirlerinin sorumluluk alanlarına girmezler. Birbirlerinden bağımsız programlama dilleri ve teknolojiler kullanabilirler.

Tek tip arayüz (Uniform Interface)

Aynı kaynağa yönelik olan tüm istekler, isteğin nereden geldiğinden bağımsız olarak aynı şekilde görünmelidir. Bu aynı zamanda istemci – sunucu bağımsızlığını da destekler. 4 temel özelliği bulunmaktadır.

  • Kaynakların tanımlanması

  • Bir kaynak için bir sunucuya yapılacak istek benzersiz bir url ile tanımlanır.

  • İstemci tarafında kaynağın değiştirilmesi

  • İstemci sunucunun kendine gönderdiği verilerde değişiklik yapabilir veya silebilir (yetkisi varsa)

  • İstemci ve sunucu birbirinin ihtiyaç duyfuğu bilgilerin tamamını gönderir

  • Sunucu istemciye göndereceği sunumun dosya tipini belirtir.

    İstemci aynı url ye istemde bulunduğunda metodu da belirtir. (GET/users vs POST/users vs) Bu da sonucu değiştirir.

  • HATEOAS (Hypermedia as the Engine of Application State)

  • Sunucu cevabın yanında farklı ek aksiyonlar için url adresleri de gönderebilir.

Durumsuzluk (Statelessness)

state: o anki mevcut vaziyet.

Durum bilgisi tutuluyorsa stateful, tutulmuyorsa stateless denir.

Stateless olması için sunucu istemci tarafından kendisine gönderilen bilgileri tutmamalıdır.

Önbelleklenebilirlik (Cacheable)

Cache ihtiyacımız olan verileri lokalde tutmaya denir. Bu da tekrar kullanımda hızı arttırır.

Sunucu gelen isteklere verilen cevapların önbelleklenebilir olup olmadığını belirtmelidir. Örneğin “Cache-Control”, “Expires” gibi HTTP başlıkları önbellek ile ilgili bilgiler taşır.

Katmanlı sistem (Layered System)

İstemci – sunucu arasındaki ilişki katmanlara ayrılabilir, ve bileşenler sadece ilişkili oldukları katmanlara karşı sorumlu olurlar.

Bu ara katmanlar gönderilen istekte veya alınan cevapta değişiklik yapmamalıdır.

İsteğe bağlı kod (Code on Demand - Optional)

Sunucu, istemci tarafına istemcinin işlevini genişletecek ek kodlar gönderebilir. Bu özellik istemci tarafında yapılması gereken işlemleri hafifletir.

Örneğin sunucu, istemci tarafına döneceği HTML dökümanın içerisine JavaScript kodları ekleyebilir.

HTTP Nedir?

Hyper Text Transfer Protocol

İstemci ile sunucu arasında veri akışının kurallarını belirler.

request - response modeline göre çalışır.

HTTP Request

4 bölümden oluşur:

  • Request Line
  • http metodu, path, http versiyon belirtilir.

  • Request headers
  • İsteğin özelliklerini isim ve değer çifti olarak belirtilir.

    Hangi header nasıl kullanılır için: developer.mozilla.org/en-US/docs/Web/HTTP/Headers

  • Boş Satır
  • header ile body i ayırır

  • Request Message Body
  • İsteğin gönderildiği kısım

HTTP Response

  • Status
  • http protokol versiyonu, http status code

  • Response headers
  • Cevabın özelliklerini isim ve değer çifti olarak belirtilir.

    Hangi header nasıl kullanılır için: developer.mozilla.org/en-US/docs/Web/HTTP/Headers

  • Boş Satır
  • header ile body i ayırır

  • Response Message Body
  • Cevabın gönderildiği kısım

HTTP Durum Kodları

Sunucu tarafından gelen cevaptaki bu 3 haneli kod sunucu tarafında olanları özetler.

  • Informational responses (Bidirimsel cevaplar) (100–199)
    • 100 Continue
    • 102 Processing
  • Successful responses (Başarılı cevaplar) (200–299)
    • 200 OK
    • 201 Created
    • 204 No Content
    • 204 ile gelen cevapların bodysi olmaz

  • Redirections (Yönlendirme cevapları) (300–399)
    • 300 Multiple Choice
    • 301 Moved Permanently
    • 304 Not Modified
  • Client errors (İstemci Hataları) (400–499)
    • 400 Bad Request
    • 401 Unauthorized
    • 403 Forbidden
    • 404 Not Found
    • 405 Method Not Allowed
  • Server errors (Sunucu Hataları) (500–599)
    • 500 Internal Server Error
    • 503 Service Unavailable

    Diğer kodlar için: developer.mozilla.org/en-US/docs/Web/HTTP/Status

HTTP Metotları

  • GET
  • Verileri almak - listelemek için kullanılan istek metodudur.

  • POST
  • Belirli bir kaynağa veri göndermek için kullanılır.

  • PUT
  • Belirli bir kaynaktaki verinin tamamının değiştirilmesi için kullanılan metodtur. Değiştirilmek istenen veriyi silip yerine yeni bir veri yazar. Bu nedenle tek bir değer değiştirmek istiyorsak diğer verileri de göndermemiz gerekir.

  • PATCH
  • Belirli bir kaynaktaki verilerin bir kısmının değiştirilmesi için kullanılan metodtur. Gönderilen veriyi değiştirir. Kalan veriyi olduğu gibi tutar.

  • DELETE
  • Belirli bir kaynaktaki verilerin silinmesi için kullanılan metodtur.

  • CONNECT
  • Genelde sss kullanılan veb sayfalarına ulaşmak için kullanılır.

  • OPTIONS
  • ilgili url de izin verilen metotları belirtir.

  • TRACE
  • genelde debug metotları için kullanılır.

  • HEAD
  • get ile benzerdir ancak sadece header bilgisini alır.

Safe Metodlar

Read only metotlardır. Sunucu tarafında değişiklik yapmazlar.

GET, HEAD, OPTIONS

Idempotent Metodlar

Tekrar durumunda sunucu state yapısında herhangi bir etki yapmazlar. Gelen cevaplar değişmezler.

safe metotlar yapısı gereği idempotenttir. GET, HEAD, OPTIONS

İlkinde değişiklik yapması önemli değil. Aynı istek gönderilmeye devam ettiğinde değişiklik yapmıyorsa idempotenttir. DELETE, PUT, TRACE

Endpoint (Sorgu Adresi)

REST API kullanımında gönderilen istek ile verilen cevap için belirlenen buluşma noktasıdır.

Root(Base) /Path yapısından oluşur, isimler kullanılır, fiil ilgili HTTP metodu ile belirtilir. Dökümantasyon tarafından belirtilir.

https://jsonplaceholder.typicode.com/posts
root: https://jsonplaceholder.typicode.com
path: /posts

hiyerarşik bir yapı kullanılır.
https://jsonplaceholder.typicode.com/posts/1/comments => id'si 1 e karşılık gelen posttaki yorumlar

Değişen değer için genelde (:) kullanılır.
/posts/:id veya /posts/{{id}}

Sorgu parametreleri için (?) kullanılır.
http://example.com/articles?sort=author&date=published

JSON Nedir?

JavaScript Object Notation

Veri depolamak veya veri iletmek için kullanılan metin tabanlı bir söz dizimi yapısıdır. Genellikle bir sunucu ve istemci arasında veri alışverişi için veya yazılımların genel ayarları için kullanılan bir formattır.

    JSON veri tipleri

  • String
  • "Sample String", "test1234", "A"
    String değerler çift tırnak içine yazılmalı

  • Number
  • 7, 3.2, -97.238

  • Boolean
  • true, false
    küçük harf ile yazılacak

  • Null
  • null
    Boş olan değerler için kullanılır.

  • Array
  • [2,3,5,7] , ["İstanbul", "Ankara", "İzmir"]
    Array içerisinde kullanılan değerler sıralı olarak listelenebilir.

  • Object
  • { "name": "Gürcan", "age":40 }
    JSON nesneleri verileri key-value çiftleri olarak tanımlar.
    key değeri çift tırnak içine yazılır.

JSON veri tipinin uygunluğunu kontrol etmek için: jsonlint.com

JSON - JavaScript - XML

Uygun JSON formatındaki bir içerik JavaScript ifadesine (expression) denk gelir.

js ifadesinde key değerleri çift tırnak içinde yazılabilir ama tercih edilmez. Çift tırnak işareti ile yazılsa da tekrar çağırıldığında tırnakları kendisi siler.

json her ne kadar js alt kümesi olsa da başka dillere rahatlıkla parse edilebilir.

XML

eXtensible Markup Language

JSON'dan önce jullanılıyordu. Ağaç yapısı şeklindedir (HTML gibi etiketler içine yazılır.) Bu ağaç yapısını kullanabilmek için önce programlama dillerine uygun olan nesne yapısına dönüştürmek gerekir.

JSON daha kolay işlenir ve daha kolay okunur.

XML'in güvenlik tarafında avantajları var.

Postman

Postman bir API platformudur. API geliştirmek , test etmek ve/veya hazır bir API kullanımı için gerekli isteklerde bulunabileceğimiz bir uygulamadır.

postman.com/downloads/ -> download ve setup

uygulama içinden + ile yeni untitled request oluşturulur.
ilgili request seçilir ve gönderilecek url girilir.
ilgili veriler body alanına json olarak yazılır.
send ile gönderilir.

Star Wars API

Bu çalışma için swapi.dev adresini kullanacağız.

postman uygulamasında SWAPI API koleksiyonu ve içine FILMS klasörü açıldı.

swapi.dev/documentation içerisinden alınan bilgilerle root: https://swapi.dev/api/ olan sorgular yapıldı.

GET ALL FILMS
GET https://swapi.dev/api/films/

GET A FILM GET https://swapi.dev/api/films/1/

SWAPI API koleksiyonu için root hep aynı olacağından değişkene atanabilir. Bunun için SWAPI API çift tıklanır. Variables ekranında baseURL değişkeni https://swapi.dev/api değeri ile oluşturulur. save ile kaydedilir.

GET ALL FILMS
GET {{baseURL}}/films/

GET A FILM
GET {{baseURL}}/films/1/

Search

Dökümantasyondan search kısmına bakılır. Bu işlem farklı API larda farklı yapılıyor olabilir.

GET {{baseURL}}/films/?search=Hope
{{baseURL}}: root
/films/: arama yapılacak kısım.
? sorgu yapıldığını ifade eder.
search: kullandığımız API ın sorgu için kullandığı key değeri.
Hope: aranacak değer.

Aranacak değer url yapısına uygun olmayan karakter içeriyorsa value sağ tıklanıp Encode URI Component yapılır.

Değişken ile sorgu

GET A FILM
GET {{baseURL}}/films/:id/
:id ifadesi sonucunda sorgu ekranında Path Variables ekranı açılır ve id key olarak atanır. Karşısına yazılacak value değerine göre de sorgu yapar.

The Movie Database API (TMDBAPI)

Bu çalışma için themoviedb.org adresini kullanacağız. Önce siteye girip kayıt oluyoruz ve giriş yapıyoruz.

profil>ayarlar>API içinde bir API key oluşturacağız. API key bizim giriş anahtaramız olacak.

postman uygulamasında TMDB API koleksiyonu ve içine MOVIE klasörü açıldı.

TMDB API döküman içinden istenilen sorgunun bilgileri ve örnekleri bulundu.

örnekte:
https://api.themoviedb.org/3/movie/popular?api_key=<<api_key>>&language=en-US&page=1
altı çizili alana api key yazılır.
https://api.themoviedb.org/3/movie/popular?api_key=7b1bf84936443d5217465b87c43a41aa&language=en-US&page=1

api_key postmande ilgili sorgunun authorization alanına da yazılabilir. API KEY seçilir.
key: api_key
value: bizim api keyimiz
add to: query params
burada uygulanan authorization metodu ilgili API nin dökümentasyonuna göre belirlendi.

root daha önceki çalışmadaki gibi değişken olarak atanabilir.

GET POPULAR MOVIES
GET {{baseURL}}/movie/popular?language=tr&page=1

GET A MOVIE
GET {{baseURL}}/movie/:movie_id
movie_id keyin valuesine istenilen filmin idsi yazılır.
authorization alanı düzenlenir.
Türkçe isteniyorsa
{{baseURL}}/movie/:movie_id?language=tr

RATE MOVIE
POST {{baseURL}}/movie/:movie_id/rating
authorization işlemi önceki gibi yapılır.
POST işlemi için session gerekir. Bunun için de request token kullanılır.

Session

CREATE REQUEST TOKEN
GET {{baseURL}}/authentication/token/new
authorization işlemi de yapılır ve gönderilir.
gelen cevaptaki request_token kopyalanır.
TMDB API variables alanına token keyi oluşturur ve value olarak kopyaladığımız değer yapıştırılır.

https://www.themoviedb.org/authenticate/{REQUEST_TOKEN} linkindeki alan request token eklenerek doldurulur ve web tarayıcıya yazılır. Gelen alan onaylanır.

CREATE SESSION ID
POST {{baseURL}}/authentication/session/new
body kısmında raw>JSON olarak:
{
"request_token": "e6a2bb9a30ed7725077e67444fba478655128027"
}
authorization işlemi de yapılır ve gönderilir.
helen cevaptaki session_id value değeri kopyalanır.
TMDB API variables alanına session_id keyi oluşturur ve value olarak kopyaladığımız değer yapıştırılır.

RATE MOVIE
POST {{baseURL}}/movie/:movie_id/rating
authorization işlemi önceki gibi yapılır.
query params içine: key: session_id value: {{session_id}}
body kısmında raw>JSON olarak:
{
"value": 6
}
send ile gönderilir

DELETE A MOVIE
DELETE {{baseURL}}/movie/:movie_id/rating
authorization işlemi önceki gibi yapılır.
query params içine: key: session_id value: {{session_id}}
send ile gönderilir.

Bearer Token (API Read Access Token) Kullanımı

API key aldığımız ekranda yer alıyor. Authorization ekranında API key yerine Bearer Token seçilir. ve token buraya yapıştırılır.

Dökümantasyona göre API key ile aynı işe yarıyor.

Fake API

Bu pratiğimizde bir Fake (göstermelik) REST API oluşturacağız. Fake REST API oluşturmanın avantajları:

  • Frontend (Ön yüz) tarafı hazır olan bir uygulamayı test etmek isteyebiliriz.
  • Yapmayı düşündüğümüz bir Backend (Arka yüz) çalışması için bir prototip oluşturmak isteyebiliriz.
  • Postman gibi bir API platformunda farklı HTTP metotlarına ait istekler gerçekleştirmek isteyebiliriz.

FAKE REST API adında bir klasör oluşturup VSC ile açılıp terminale:
npm init

FAKE API için JSON SERVER paketi kullanacağız. Dökümantasyon github.com/typicode/json-server

Dökümantasyonda kurulum için npm install -g json-server yazıyor. -g burada yüklemeyi global hale getiriyor. Biz sadece bu projede kullanacağımız için terminale:
npm i json-server

Dökümantasyona göre db.json oluşturulur ve içine JSON formatında veriler yüklenir. Biz api klasörü içine employees.json dosyası oluşturup istediğimiz veriyi Json formatında ekliyoruz. Biz employee ve role adında iki veri grubu oluşturduk.

DB tipi veri yaratmak için mockaroo.com

Dökümantasyona göre terminale json-server --watch db.json yazılarak server başlatılır. Biz başka bir klasör kullanacağımız için package.json script alanına
"start:server": "json-server --watch api/employees.json" yazıp kaydediyoruz ve sonra terminale
npm run start:server yazıyoruz.
terminalde gelen cevapta api için root ve path bilgilerini alıyoruz. Aynı yerdeki home page ise resources vs hakkında bilgi verir.

Şimdi postman ile request gönderiyoruz. Önce yeni bir collection (FAKE API) oluşturuyoruz ve sonra da istekleri oluşturup gönderiyoruz. FAKE API collection variables baseURL: http://localhost:3000

GET ALL EMPLOYEES
GET {{baseURL}}/employee

GET EMPLOYEE DETAIL
GET {{baseURL}}/employee/:id
Dökümantasyona göre / dan sonra id yazılıyor. Biz de buraya id değişkeni yazdık. Değişken değerini de Path Variables içine yazdık.

FILTER EMPLOYEES
GET {{baseURL}}/employee?gender=Female
Gender değeri Female olanları verir.

Birden fazla sorgu yapılacağında arasına & konulur.

_page: pagination için sayfanın numarasını verir.
_limit: bir sayfada gösterilecek veri miktarını verir.
_sort: sıralama
_order: sıralama yönü: asc veya desc alır. varsayılanı asc dir.
q: search için

GET {{baseURL}}/employee?gender=Female&_page=1&_limit=2&_sort=first_name&_order=desc&q=duff
sorgu:
gender: Female
kaçıncı sayfa: 1
sayfadaki veri sayısı: 2
sıralama: first name
sıralama: azalan
aranan değer: duff

bizim oluşturduğumuz database kurgusunda role - employee ilişkisinde employee child, role ise parent. Çünkü her employee bir role karşılık geliyor.

_embed: child içeren parentleri sıralar. _expand: parent içindeki çocukları sıralar.

GET ROLES WITH EMPLOTEES
GET {{baseURL}}/roles/1?_embed=employee
rolleri ve her rol için o role sahip çalışanları verir.

GET EMPLOYEES WITH ROLES
GET {{baseURL}}/employee?_expand=role

ADD AN EMPLOYEE
POST {{baseURL}}/employee
mesajın body kısmına oluşturulacak employee bilgileri eklenir. Id eklenmez. Bunu db kendi verir.

DELETE AN EMPLOYEE
DELETE {{baseURL}}/employee/:id
id değişkenine yazılan id ye karşılık gelen veriyi siler.

UPDATE AN EMPLOYEE
PATCH {{baseURL}}/employee/:id
id değişkenine yazılan id ye karşılık gelen veriyi body de yazılan key-value değerine göre günceller.

PATCH metodu ile sadece değiştirilecek veri çifti gönderilir. PUT metodunda ise tüm veriler gönderilir.

cURL Kullanımı

URL üzerinden veri transferi yapmamızı sağlayan bir komut satırı aracıdır. REST API çerçeverinde sorgu adreslerine yapılan isteklerde sıklıkla kullanılır. HTTP, HTTPS, FTP, FTPS, GOPHER, GOPHERS, IMAP, IMAPS vs.. bir çok protokolü desteklemektedir.

curl.se üzerinden indirilerek veya git bash ile kullanılabilir. Biz git bash kullanacağız.

git bash terminaline:
curl https://swapi.dev/api/planets/1/ yazıldığında ilgili linke get request yapar ve sonucu terminalde gösterir.

git bash terminaline:
curl -i https://swapi.dev/api/planets/1/ yazıldığında ilgili linke request yapar ve header bilgilerini terminalde gösterir.

cURL komut sseçenekleri

-i (--include): Çıktı içerisinde HTTP başlıklarını da gösterir.
-I (--head): Yalnızca HTTP başlıklarını görmek için kullanılır.
-o (--output) <file> : Çıktıyı bir dosyaya yazdırmak için kullanılır.
-v (--verbose): Daha fazla detay.
-s: Sadece istenilen veri

Daha Önce Yaptığımız Bazı İşlemlerin cURL Versiyonları

GET A FILM DTEAIL (SWAPI)
curl https://swapi.dev/api/films/1/

GET POPULAR MOVIES (TMDBAPI)
curl https://api.themoviedb.org/3/movie/popular?api_key=your_api_key
your_api_key yerine kendi api keyimiz yazılır.

GET POPULAR MOVIES (TMDBAPI) -d seçeneği ile
curl -X GET -G -d api_key=your_api_key https://api.themoviedb.org/3/movie/popular
-X metodu belirtir. GET için method belirmek gerekmez.
-G GET ile gönderilecek veriyi belirtir
-d gönderilen data flagı

GET A MOVIE DETAIL (TMDBAPI) -d seçeneği ile
curl -X GET -G -d api_key=your_api_key https://api.themoviedb.org/3/movie/:movie_id
:movie_id yerine istenilen filmin id si yazılır.

GET ALL EMPLOYEES (Fake API)
curl http://localhost:3000/employees

GET AN EMPLOYEE DETAIL (Fake API)
curl http://localhost:3000/employees/:employee_id
:employee_id yerine istenilen verinin id si yazılır.

POST AN EMPLOYEE (Fake API)
curl -X POST -H "Content-Type: application/json" -d '{ "first_name": "Ricardo", "last_name": "Quaresma", "email": "ricardo@test.tr", "gender": "Male", "roleId": 3 }' http://localhost:3000/employees
-H header göndermek için flag

DELETE AN EMPLOYEE (Fake API)
curl -X DELETE http://localhost:3000/employees/:employee_id

UPDATE AN EMPLOYEE (Fake API) - PATCH
curl -X PATCH -H "Content-Type: application/json" -d '{ "first_name": "Ricardo", "last_name": "Quaresma"}' http://localhost:3000/employees/:employee_id
Sadece gönderilen veriyi günceller.

UPDATE AN EMPLOYEE (Fake API) - PUT
curl -X PUT -H "Content-Type: application/json" -d '{ "first_name": "Ricardo", "last_name": "Quaresma"}' http://localhost:3000/employees/:employee_id
İlgili id deki tüm veriyi silip gönderdiğimizi yazar

API'dan Veriyi Node ile Sayfaya Aktarmak (fetch)

Bu kısmı diğer derslerden brinde gördüm. Biraz da kendim araştırdım. Gerekli olursa diye buraya da ekliyorum.

const url = "https://swapi.dev/api/films/"

app.get('/', async (req, res) => {
fetch(url)
.then(response => response.json())
.then(json => {
console.log("filmler alındı")
return films = json.results
})
.then(films => res.status(200).render('index', {films}, console.log("render OK")))
});

veya
const url = "https://swapi.dev/api/films/"

app.get('/', async (req, res) => {
await fetch(url)
.then(response => response.json())
.then(json => {
console.log("filmler alındı")
return films = json.results
})
res.status(200).render('index', {films}, console.log("render OK")) });

fatch kullanımı için: developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

axios benzer işlemleri daha da kolay yaptığımız bir kütüphane.