Diyelim ki JSON formatındaki bir veriyi, verilen bağlantıya HTTP protokolü üzerinden POST yöntemiyle göndermemiz gerekiyor. Bu işlemi yapabileceğimiz HTTPie, HTTP Prompt, Wget gibi çeşitli araçlar mevcut. Biz bu işlemi cURL aracıyla, Linux komut satırı üzerinden yapalım. 

cURL, URL söz dizimini kullanarak HTTP ve çeşitli protokollerde istekler yapmak için kullanılan bir komut satırı yardımcı programıdır. Protokoller üzerinden veri aktarımı sağlamak (dosya almak ya da göndermek vb.) için kullanılır. Komut satırı aracıyla birlikte, libcurl adında bir URL transfer kütüphanesi sunar. Bu araç sayesinde bir sunucuya (ya da sunucudan), komut satırını kullanarak HTTPS istekleri yapabilir, elimizdeki verileri aktarabilir ve dönen cevapları alabiliriz.

libcurl: cURL projesi tarafından sunulan ve cURL komut satırı aracı ile birlikte gelen, ücretsiz bir URL transfer kütüphanesidir. Kendi klavuz sayfasında belirtildiğine göre HTTPS yanında DICT, FILE, FTP, FTPS, GOPHER, HTTP, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET ve TFTP standartlarını da destekliyor. Taşınabilir bir kütüphane olduğu için bir çok işletim sisteminde çalışabilir.

cURL Kurulumu

Bazı Linux sürümleriyle beraber gelen bu aracın, sisteminizde yüklü olup olmadığını anlamak için şu komutu kullanın.

$ curl -V

Eğer bu komuttan sonra aşağıdaki gibi bir versiyon bilgisi dönüyorsa cURL aracı sisteminizde kurulu demektir.

curl 7.55.1 (x86_64-pc-linux-gnu) libcurl/7.55.1 OpenSSL/1.0.2g zlib/1.2.11 libidn2/2.0.2 libpsl/0.18.0 (+libidn2/2.0.2) librtmp/2.3
    Release-Date: 2017-08-14
    Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp 
    Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets HTTPS-proxy PSL 

Versiyon bilgisi yerine komut bulunamadı uyarısı ekranda görünüyorsa, Debian tabanlı sistemler için alttaki komutla sisteminize kurabilirsiniz.

$ sudo apt-get install curl

Redhat tabanlı sistemler için de alttaki komutu kullanabilirsiniz.

$ yum install curl
Not: Diğer platformlar için yükleme paketlerine bu adresten ulaşabilirsiniz. 

Kurulum tamamlandığında, yukarıdaki komutu tekrar çalıştırdığınızda artık Curl versiyon bilgisini görebilmelisiniz.

$ curl -V
    
    curl 7.55.1 (x86_64-pc-linux-gnu) libcurl/7.55.1 OpenSSL/1.0.2g zlib/1.2.11 libidn2/2.0.2 libpsl/0.18.0 (+libidn2/2.0.2) librtmp/2.3
    Release-Date: 2017-08-14
    Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp 
    Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets HTTPS-proxy PSL

cURL Kullanımı

Bu aşamadan itibaren artık Curl kullanmaya başlayabiliriz. Hızlı bir deneme olarak, komut satırına aşağıdaki kodu yazalım.

$ curl wttr.in/izmir

Terminal ekranınızda aşağıdaki gibi, wttr.in sitesinden alınan İzmir’e ait hava durumu bilgileri görünmeli.

firat@ubuntu-f:~$ curl http://wttr.in/izmir
    Weather report: Izmir, Turkey
    
         \   /     Clear
          .-.      19 °C          
       ― (   ) ―   ↓ 0 km/h       
          `-’      10 km          
         /   \     0.0 mm         
                                                           ┌─────────────┐                                                       
    ┌──────────────────────────────┬───────────────────────┤  Thu 08 Aug ├───────────────────────┬──────────────────────────────┐
    │            Morning           │             Noon      └──────┬──────┘     Evening           │             Night            │
    ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
    │     \   /     Sunny          │     \   /     Sunny          │     \   /     Sunny          │     \   /     Clear          │
    │      .-.      28..29 °C      │      .-.      33..35 °C      │      .-.      35 °C          │      .-.      32..36 °C      │
    │   ― (   ) ―   ↘ 7-8 km/h     │   ― (   ) ―   → 13-15 km/h   │   ― (   ) ―   ↘ 18-24 km/h   │   ― (   ) ―   ↗ 7-14 km/h    │
    │      `-’      10 km          │      `-’      10 km          │      `-’      10 km          │      `-’      10 km          │
    │     /   \     0.0 mm | 0%    │     /   \     0.0 mm | 0%    │     /   \     0.0 mm | 0%    │     /   \     0.0 mm | 0%    │
    └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
                                                           ┌─────────────┐                                                       
    ┌──────────────────────────────┬───────────────────────┤  Fri 09 Aug ├───────────────────────┬──────────────────────────────┐
    │            Morning           │             Noon      └──────┬──────┘     Evening           │             Night            │
    ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
    │     \   /     Sunny          │     \   /     Sunny          │     \   /     Sunny          │     \   /     Clear          │
    │      .-.      29 °C          │      .-.      35..37 °C      │      .-.      38 °C          │      .-.      36..39 °C      │
    │   ― (   ) ―   ↘ 6-7 km/h     │   ― (   ) ―   ↘ 10-11 km/h   │   ― (   ) ―   ↓ 28-37 km/h   │   ― (   ) ―   ↓ 14-30 km/h   │
    │      `-’      10 km          │      `-’      10 km          │      `-’      10 km          │      `-’      10 km          │
    │     /   \     0.0 mm | 0%    │     /   \     0.0 mm | 0%    │     /   \     0.0 mm | 0%    │     /   \     0.0 mm | 0%    │
    └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
                                                           ┌─────────────┐                                                       
    ┌──────────────────────────────┬───────────────────────┤  Sat 10 Aug ├───────────────────────┬──────────────────────────────┐
    │            Morning           │             Noon      └──────┬──────┘     Evening           │             Night            │
    ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
    │     \   /     Sunny          │     \   /     Sunny          │     \   /     Sunny          │     \   /     Clear          │
    │      .-.      29 °C          │      .-.      36..37 °C      │      .-.      38..40 °C      │      .-.      35..38 °C      │
    │   ― (   ) ―   ↙ 17-19 km/h   │   ― (   ) ―   ↙ 23-27 km/h   │   ― (   ) ―   ↓ 26-35 km/h   │   ― (   ) ―   ↓ 15-32 km/h   │
    │      `-’      10 km          │      `-’      10 km          │      `-’      10 km          │      `-’      10 km          │
    │     /   \     0.0 mm | 0%    │     /   \     0.0 mm | 0%    │     /   \     0.0 mm | 0%    │     /   \     0.0 mm | 0%    │
    └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
    
    Follow @igor_chubin for wttr.in updates

cURL hiçbir parametre girilmediğinde, varsayılan olarak verilen adrese bir GET isteği yapar. Bu istek sonucu karşı adresten bir HTML bloğu alır. Bu blok, web tarayıcısında gördüğümüz site görüntüsünün kaynak kodlarıdır. İnternet tarayıcıları bu kodla sitenin görüntüsünü oluşturarak bize gösterirken, komut satırı bu özelliğe sahip olmadığı için sadece kaynak kodunu görürüz.

Bu işlemi farklı veri türleriyle yapmak istediğimizde, bazı parametreleri cURL aracına girmemiz gerekiyor. Şimdi içinde örnek mesaj bilgileri içeren bir JSON yapısı hazırlayalım ve bazı gerekli parametreleri, cURL aracını kullanarak bir URL’e gönderelim.

cURL ile Post İsteği

cURL aracı ile POST isteği gönderirken kullanmamız gereken -X, -H, -d ve --data-urlencode gibi bazı parametreler var. Ayrıca kullanacağımız URL'i de bu aşamada cURL aracına girmemiz gerekiyor.

Şimdi bu parametrelere bakalım.

-X veya --request

Bu parametre ile verimizin hangi yöntemle gönderileceğini belirliyoruz. Kendisinden sonra, kullanmak istediğimiz yöntemi belirtiyoruz (POST için -X POST). Bu parametre yerine --request de kullanabilirsiniz (Örn: --request POST). İki parametre de aynı işlemi yapacaktır. Parametreyi Curl aracına aşağıdaki gibi tanımlıyoruz.

curl -X POST
veya
curl --request POST
Not: Tek çizgi ile başlayan parametrelerden hemen sonra boşluk bırakılması önerilmesine rağmen, parametre ile değer arasında boşluk bırakmaya gerek yoktur. Ancak çift çizgili parametrelerden sonra değer girilmeden önce bir boşluk bırakılması gerekir.

Ancak komut bu şekilde çalışmayacaktır. cURL, URL'in belirtilmediğine dair bir hata mesajı döndürür. Eklememiz gereken bir kaç parametre daha var.

-H veya --header

Gönderdiğimiz verinin türünü (medya türü) bu parametreler ile belirliyoruz. Kullanabileceğiniz bütün türleri görmek için bu bağlantıya bakabilirsiniz. button ya da link gibi, HTML-form veriler, sunucuya gönderilmeden önce URL kodlaması (yüzde kodlaması) denilen bir yöntemle kodlanır. URL kodlaması, bir URL'deki ?, / ve = gibi özel karakterleri %3F, %2F ve %3D gibi kodlara dönüştürür. Bu kodlama işlemi belirsizliği ortadan kaldırıyor. Örneğimizde kodlanmamış JSON yapısı göndereceğimiz için, aşağıdaki iki türü de kullanabiliriz.

  • application/json: Kodlanmamış halde JSON verisi bu türde gönderilebilir.

  • application/x-www-form-urlencoded: Önceden kodlanmış, kodlanmaya ihtiyaç duymayan HTML-form verileri bu türde gönderilir.

Bu türlerden birini, -H veya --header parametrelerini kullanarak cURL aracına aşağıdaki gibi tanımlıyoruz.

curl -X POST -H "Content-type: application/json"
Veya application/x-www-form-urlencoded türünü komuta aşağıdaki gibi ekleyebiliriz.
curl -X POST -H "Content-type: application/x-www-form-urlencoded"

-d veya - -data

Gönderilen veriler bu parametreye giriliyor. Sunucuya POST ile gönderilen bu veriler, HTTP istek gövdesinde saklanır. Örnek bir HTML kod oluşturup --data parametresine ekleyelim.

curl -X POST -H "Content-type: application/x-www-form-urlencoded" 
    --data "<https://example.com/|Buraya tıklayın.>"

JSON yapılarını gönderirken URL kodlamaya ihtiyaç duymamıştık fakat buradaki gibi HTML-form veriler gönderilirken kodlanması gerekir. Ancak -d ve --data parametreleri ile girilen veriler kodlanmaz. Üstelik -H parametresine de, verinin zaten kodlanmış olduğunu belirten application/x-www-form-urlencoded seçeneğini girdik. Eğer bu şekilde gönderiyorsak verinin önceden kodlanarak komuta yerleştirilmesi gerekir. Bir örneğine aşağıda görebilirsiniz.

curl -X POST -H "Content-type: application/x-www-form-urlencoded" 
    --data "%3Chttps%3A%2F%2Fexample.com%2F%7CBuraya%20t%C4%B1klay%C4%B1n.%3E"

Kodlama işlemini otomatik olarak cURL'in yapmasını sağlayacak bir parametreyi biraz sonra kullanacağız. Ama öncelikle örnek bir JSON yapısı oluşturalım. İçine birden fazla anahtar : değer ikilisi ekleyelim.

{
       "username": "firat",
       "channel": "#tasarım",
       "icon_emoji": ":ghost:",
       "text": "Bu bir deneme mesajıdır.\nBu cümle ise ikinci satıra yazılır. <https://example.com/|Buraya tıklayın.>"
    }
Şimdi bunu, daha önceki cURL komutuna --data parametresi ile ekleyelim.
curl -X POST -H "Content-type: application/json"
    --data "{
       "username": "firat",
       "channel": "#tasarım",
       "icon_emoji": ":ghost:",
       "text": "Bu bir deneme mesajıdır.\nBu cümle ise ikinci satıra yazılır. <https://example.com/|Buraya tıklayın.>"}"
Ancak yine URL kodlama yapmayan --data parametresi ile gönderiyoruz ve kodlanmamış JSON türünü ifade eden application/json seçeneğini giriyoruz. Ve verinin içinde HTML-form ifadeler var. Eğer verilerimizi göndereceğimiz API, hem JSON yapısı kullanıyor hem de JSON içindeki HTML-form değerleri kodlamamızı zorunlu kılıyorsa, bu parametreye gireceğimiz verinin daha önceden kodlamasının yapılmış olaması gerekiyordu.

--data-urlencode

Henüz kodlamadığınız verileri göndermenize yardımcı olmak için, cURL --data-urlencode seçeneği sunar . Bu seçenek, verilerin gönderilmeden önce URL kodlanmasını sağlar. Bunu yapabilmek için, veri kümesi bir anahtara = ile ilişkilendirilir. Ve bu ikili blok --data-urlencode parametresine girilir.
curl -X POST -H "Content-type: application/x-www-form-urlencoded"
    --data-urlencode "payload={
       "username": "firat",
       "channel": "#tasarım",
       "icon_emoji": ":ghost:",
       "text":"Bu bir deneme mesajıdır.\nBu cümle ise ikinci satıra yazılır. <https://example.com/|Buraya tıklayın.>"}"
Bu şekilde cURL veriyi göndermeden önce, = sonrasındaki veriyi tamamen kodlamadan geçirir. Anahtar ismine (payload) ve = atama operatörüne dokunmaz. Dolayısıyla, bunların önceden zaten kodlanmış olması gerekir. Anahtar adı genelde bağlantı kurulan sistem tarafından belirlenmiştir. Ben örnek olarak, Slack Incoming Webhook bağlantısında istenen payload anahtarını kullandım. Yukardaki kod bloğu, gönderilmeden önce cURL tarafından aşağıdaki duruma getirilir.
curl -X POST -H "Content-type: application/x-www-form-urlencoded"
    --data-urlencode "payload=%7B%0A%20%20%20%22username%22%3A%20%22firat%22%2C%0A%20%20%20%22channel%22%3A%20%22%23tasar%C4%B1m%22%2C%0A%20%20%20%22icon_emoji%22%3A%20%22%3Aghost%3A%22%2C%0A%20%20%20%22text%22%3A%22Bu%20bir%20deneme%20mesaj%C4%B1d%C4%B1r.%5CnBu%20c%C3%BCmle%20ise%20ikinci%20sat%C4%B1ra%20yaz%C4%B1l%C4%B1r.%20%3Chttps%3A%2F%2Fexample.com%2F%7CBuraya%20t%C4%B1klay%C4%B1n.%3E%22%0A%7D"
Eğer herhangi bir veri formatı belirtilmezse cURL veriyi ön tanımlı olarak application/x-www-form-urlencoded olarak kabul ediyor. Dolayısıyla, eğer HTML-form tipinde karakterlerin bulunduğu bir veri gönderiyorsak, ayrıca bir de -H parametresi ile format belirtmemize gerek kalmıyor. Yani komutumuzdan -H parametresini ve içerdiği değeri çıkartarak aşağıdaki gibi yazdığımızda da amacımıza ulaşmış oluyoruz.
curl -X POST
    --data-urlencode "payload={
       "username": "firat",
       "channel": "#tasarım",
       "icon_emoji": ":ghost:",
       "text":"Bu bir deneme mesajıdır.\nBu cümle ise ikinci satıra yazılır. <https://example.com/|Buraya tıklayın.>"}"
Öneri: Amacınız komut satırını kullanarak gönderim yapmaksa, ek URL kodlaması gerektirmeyen ve daha kısa olan ikinci yöntemi seçmeniz daha mantıklı olacaktır.
Son parametre olarak da, veriyi göndereceğiniz adresi cURL aracına giriyoruz. Örnekte, Slack platformuna ait bir webhook incoming url adresini giriyorum. Bütün bu işlemlerden sonra kod yapımızın son halini aşağıda görebilirsiniz.
curl -X POST
    --data-urlencode "payload={
       "username": "firat",
       "channel": "#tasarım",
       "icon_emoji": ":ghost:",
       "text":"Bu bir deneme mesajıdır.\nBu cümle ise ikinci satıra yazılır."}" https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Yukarıdaki kod blokları, sayfada daha okunabilir olması için alt alta bir kaç satırda yazıldı. Ve bir alt satıra geçmek için de enter tuşu kullanıldı. Fakat komut satırında enter tuşuna basıldığında komutu çalıştırmaya başlar. Bu kodlar da kopyalanıp yapıştırıldığında içindeki enter komutları aynı işi görecektir. Bu aşamada, kod bloğumuzu komut satırında işlenebilir hale getireceğiz. Bunun için sıkça kullanacağımız ters eğik çizgi \ hakkında biraz bilgi sahibi olmamız gerekiyor. Linux komut satırında ters eğik çizgi \, kendisinden sonra gelen karakteri işlevsizleştiren bir parametredir(\n kullanımı hariç). Biz de kod içindeki enter komutlarını etkisiz hale getirmek için, her enter komutundan önce bir ters eğik çizgi koyalım.
curl -X POST \
    --data-urlencode "payload = { \
       "username": "firat", \
       "channel": "#tasarım", \
       "icon_emoji": ":ghost:", \
       "text": "Bu bir deneme mesajıdır.\nBu cümle ise ikinci satıra yazılır. <https://example.com/|Buraya tıklayın.>" }" \
    https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Bu işlem sadece kodların daha okunabilir olması amacıyla yapıldı. Siz bütün bu komutları, aşağıdaki gibi alt satıra geçmeden tek satır halinde de yazabilirsiniz.
curl -X POST --data-urlencode "payload = { "username": "firat", "channel": "#tasarım", "icon_emoji": ":ghost:", "text":"Bu bir deneme mesajıdır.\nBu cümle ise ikinci satıra yazılır. <https://example.com/|Buraya tıklayın.>" }" https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Veri içindeki JSON bloğunun doğası gereği, anahtar ve değer ikilileri " çift tırnak karakteri içine alınıyor. Ancak Bash kabuğu, bu çift tırnak karakterlerini birer string değer olarak değil, string küme başlangıcı ve bitişi olarak algılıyor. Ve --data-urlencode veri başlangıcı ile, JSON çift tırnaklarını karıştırıyor. Bu sorunu aşmak için de \ ters eğik çizgiyi kullanarak " işaretinin komut işlevini yitirmesini sağlayabiliyoruz. Komutu çalıştırdığımızda, ters eğik çizgi görevini yaparak kendini imha ediyor yani çıkan sonuçta görünmüyor. Bizim oluşturduğumuz kod bloğunda da buna benzer bir durum var. Dikkat ettiyseniz en içte bir JSON yapımız, bu yapıyı taşıyan payload adında bir anahtarımız ve bu anahtarı da taşıyan --data-urlencode adında bir Curl parametremiz var.


Yani iç içe geçmiş tırnaklar söz konusu. İşte bu noktada komut satırının, göndereceğimiz JSON yapımızdaki çift tırnak işaretlerini komut yerine birer string ifade gibi yorumlamasını sağlamak için, iç blokta bulunan tırnakların hepsinin önüne ters eğik çizgi \ koymamız gerekiyor. Çünkü iç blokta bulunan JSON yapısına ait çift tırnak karakterleri, komut satırı tarafından değil sunucu tarafında verimizi karşılayacak olan API içinde işlenmeli.
$ curl -X POST \
    --data-urlencode "payload = { \
       \"username\": \"firat\", \
       \"channel\": \"#tasarım\", \
       \"icon_emoji\": \":ghost:\", \
       \"text\": \"Bu bir deneme mesajıdır.\nBu cümle ise ikinci satıra yazılır. <https://example.com/|Buraya tıklayın.>" }" \
    https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Komut bu haliyle, geçerli bir URL tanımlanıp, komut satırında çalıştırılabilir (Kod içindeki URL ve bilgiler sunum amaçlıdır). Aynı kodu bir de tek satır olarak görelim.
$ curl -X POST --data-urlencode "payload = { \"username\": \"firat\", \"channel\": \"#tasarım\", \"icon_emoji\": \":ghost:\", \"text\": \"Bu bir deneme mesajıdır.\nBu cümle ise ikinci satıra yazılır. <https://example.com/|Buraya tıklayın.>" }" https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
cURL ile yukarıdaki JSON veri bloğu kullanılarak, Slack üzerine gönderilen bir mesajı aşağıda görebilirsiniz.