Takip et

Full Stack Geliştirici Yolculuğu: Gün 6-9’da Neler Öğrenilir?

Full stack geliştirici olma yolculuğunuzun 6, 7, 8 ve 9. günlerinde sizi neler bekliyor? Frontend’den backend’e, veritabanından deployment’a temel adımları keşfederken bu dört kritik günü en verimli şekilde değerlendirin.

Full stack geliştiricinin en temel sorumluluklarından biri, kullanıcıların doğrudan etkileşime geçtiği arayüzleri hem estetik hem de işlevsel açıdan kusursuz hale getirmektir. Yolculuğumuzun 6. gününde, frontend geliştirmenin inceliklerine dalıyor ve özellikle kullanıcı deneyimini (UX) nasıl optimize edebileceğimize odaklanıyoruz. Çünkü bir uygulamanın başarısı, sadece arka plandaki güçlü algoritmalarla değil, aynı zamanda kullanıcıların onu ne kadar rahat ve keyifli kullandığıyla da ölçülür. Bu nedenle, sadece kod yazmakla kalmayıp, aynı zamanda kullanıcıların beklentilerini anlamak ve karşılamak büyük önem taşır.

Öncelikle, mobil uyumluluk ve duyarlı tasarım (responsive design) konularına değinmek elzemdir. Günümüz dünyasında internet kullanıcılarının büyük bir kısmı web sitelerine mobil cihazlarından erişiyor. Bu durum, uygulamalarımızın farklı ekran boyutlarına ve cihazlara sorunsuz bir şekilde adapte olmasını zorunlu kılıyor. CSS Flexbox ve Grid gibi modern düzenleme araçları, bu uyumluluğu sağlamak için vazgeçilmezdir. Örneğin, bir e-ticaret sitesinde ürün listelerinin küçük ekranlarda alt alta, geniş ekranlarda ise yan yana düzenlenmesi, kullanıcı deneyimini doğrudan etkiler. Bu tür düzenlemeleri yaparken, yalnızca estetik değil, aynı zamanda sayfa yükleme hızı gibi performans metriklerini de göz önünde bulundurmalıyız. Daha az görsel istek, optimize edilmiş görseller ve uygun önbellekleme stratejileri, bir web sayfasının mobil cihazlarda ne kadar hızlı yüklendiğini belirleyen kritik faktörlerdir.

JavaScript tarafında ise, DOM manipülasyonları ve olay yönetimi (event handling) becerilerimizi pekiştirmemiz gerekiyor. Kullanıcının bir butona tıklaması, bir formu doldurması veya bir öğenin üzerine gelmesi gibi etkileşimleri doğru bir şekilde yönetmek, dinamik ve interaktif bir arayüz oluşturmanın anahtarıdır. Modern JavaScript çerçeveleri (React, Vue, Angular gibi), bu tür işlemleri çok daha kolay ve yönetilebilir hale getirse de, temel JavaScript bilgisinin sağlam olması, bu çerçeveleri daha etkin kullanabilmemiz için hayati öneme sahiptir. Ayrıca, frontend performansını artırmak için asenkron JavaScript kullanımı da kritik bir beceridir. Örneğin, bir API’den veri çekerken sayfanın kilitlenmesini önlemek için async/await yapısını kullanmak, kullanıcıya kesintisiz bir deneyim sunar. Geliştirici konsolundaki performans araçlarını kullanarak, sayfamızdaki yavaş çalışan kısımları tespit edip optimize edebiliriz. Bu süreçte, gereksiz yeniden çizimleri (reflow/repaint) azaltmak, büyük DOM ağaçlarını optimize etmek ve animasyonları CSS tabanlı yapmak gibi teknikler oldukça faydalıdır.

Uzman İpucu: Bir web uygulamasının mobil uyumluluğunu test ederken sadece tarayıcınızın geliştirici araçlarını değil, farklı fiziksel cihazlarda da testler yaparak gerçek kullanıcı deneyimini simüle edin. Bu, beklenmedik düzenleme veya performans sorunlarını erken aşamada tespit etmenizi sağlar.

Son olarak, erişilebilirlik (accessibility) kavramına değinmek zorundayız. Web uygulamalarımızın herkes tarafından, engelli bireyler de dahil olmak üzere, rahatça kullanılabilir olması bir etik sorumluluktur ve çoğu ülkede yasal bir gerekliliktir. Anlamsal HTML (semantic HTML) kullanmak, uygun ARIA (Accessible Rich Internet Applications) rollerini ve etiketlerini eklemek, klavye navigasyonunu sağlamak ve yeterli renk kontrastı sunmak, erişilebilir bir arayüz oluşturmanın temel adımlarıdır. Örneğin, bir görsel için alt etiketi eklemek, ekran okuyucu kullanan bir kullanıcının o görselin içeriğini anlamasına yardımcı olur. Bu küçük detaylar, uygulamanızın daha geniş bir kitleye ulaşmasını ve kapsayıcı olmasını sağlar. Frontend geliştirme, sadece kod yazmak değil, aynı zamanda kullanıcıların ihtiyaçlarını ve beklentilerini anlamakla ilgili bir sanattır.

Gün 7: API Mimarileri ve RESTful Servislerin Temelleri Nasıl Atılır?

Full stack geliştirici yolculuğumuzun 7. gününe geldiğimizde, artık uygulamamızın “beyni” olan backend kısmına ve onunla etkileşim kurmanın ana yolu olan API’lere odaklanıyoruz. API (Application Programming Interface), farklı yazılım bileşenlerinin birbiriyle iletişim kurmasını sağlayan kurallar ve protokoller bütünüdür. Bir frontend uygulamasının bir sunucudan veri istemesi veya sunucuya veri göndermesi gerektiğinde, bu iletişim API’ler aracılığıyla gerçekleşir. Günümüzde en yaygın API mimarilerinden biri olan RESTful servisler, basitliği, ölçeklenebilirliği ve standart HTTP yöntemlerini kullanması sayesinde büyük popülerlik kazanmıştır. RESTful API’ler, kaynaklara (resources) URI’lar (Uniform Resource Identifiers) aracılığıyla erişir ve bu kaynaklar üzerinde CRUD (Create, Read, Update, Delete) operasyonlarını gerçekleştirmek için HTTP metotlarını (GET, POST, PUT, DELETE) kullanır.

Örneğin, bir e-ticaret uygulamasında ürünleri listelemek için GET /api/products isteği gönderebilirsiniz. Yeni bir ürün eklemek için POST /api/products adresine ürün bilgilerini içeren bir istek yollayabilirken, mevcut bir ürünü güncellemek için PUT /api/products/{id} ve ürünü silmek için DELETE /api/products/{id} kullanırız. Bu standartlaşmış yöntemler, API’leri hem geliştiriciler için daha anlaşılır hem de farklı platformlar arasında kolayca entegre edilebilir hale getirir. Backend geliştirme söz konusu olduğunda, Node.js ve Express.js gibi teknolojiler genellikle tercih edilir. Node.js, JavaScript’i sunucu tarafında çalıştırmamızı sağlarken, Express.js ise Node.js üzerinde web uygulamaları ve API’ler geliştirmek için hızlı ve minimalist bir çerçeve sunar. Aşağıdaki basit Express.js kodu, bir GET isteğine nasıl yanıt verileceğini göstermektedir:


const express = require('express');
const app = express();
const PORT = 3000;

// JSON body parser'ı etkinleştir
app.use(express.json());

// Tüm ürünleri döndüren bir GET rotası
app.get('/api/products', (req, res) => {
    const products = [
        { id: 1, name: 'Laptop', price: 1200 },
        { id: 2, name: 'Mouse', price: 25 }
    ];
    res.json(products); // JSON formatında yanıt gönder
});

// Sunucuyu başlat
app.listen(PORT, () => {
    console.log(Sunucu http://localhost:${PORT} adresinde çalışıyor);
});
    

Bu kod bloğu, /api/products adresine yapılan bir GET isteğine sabit bir ürün listesiyle yanıt veren çok temel bir API örneğidir. Gördüğünüz gibi, Express.js, rotaları tanımlamak ve HTTP isteklerine yanıt vermek için son derece basit ve anlaşılır bir yapı sunar. Ancak, gerçek dünya uygulamalarında, bu rotalar genellikle bir veritabanıyla etkileşime girerek dinamik veriler çeker veya kaydeder. Güvenlik, bir API geliştirirken göz ardı edilmemesi gereken kritik bir faktördür. API anahtarları, JWT (JSON Web Tokens) tabanlı kimlik doğrulama (authentication) ve yetkilendirme (authorization) mekanizmaları, API'lerinizi yetkisiz erişime karşı korumanın yaygın yollarıdır. Ayrıca, verinin doğrulanması (validation) ve sanitasyonu (sanitization) da önemlidir, böylece kötü niyetli girdiler veya hatalı veriler uygulamanızın çökmesine veya güvenlik açıklarına yol açmaz. Middleware kullanımı, Express.js'te bu tür güvenlik kontrollerini ve diğer işlem adımlarını (logging gibi) merkezi bir şekilde yönetmenizi sağlar.

Uzman İpucu: API'lerinizi tasarlarken, kaynaklarınızı tutarlı bir şekilde adlandırın ve HTTP metotlarını doğru amaçla kullanmaya özen gösterin. Bu, API'nizin kolay anlaşılabilir ve bakımı yapılabilir olmasını sağlar.

Son olarak, API dokümantasyonu da bir o kadar önemlidir. Özellikle büyük projelerde veya ekip halinde çalışırken, geliştiricilerin API'nizin nasıl çalıştığını, hangi endpoint'lerin olduğunu, hangi parametreleri beklediğini ve ne tür yanıtlar döndürdüğünü bilmesi gerekir. Swagger/OpenAPI gibi araçlar, API dokümantasyonunu otomatik olarak oluşturmanıza ve güncel tutmanıza yardımcı olabilir. Bu sayede, hem kendi ekibinizin hem de harici geliştiricilerin API'nizi kolayca entegre etmesini sağlarsınız. API geliştirme, bir full stack geliştiricinin backend yeteneklerinin temelini oluşturur ve bu beceriler, modern web uygulamalarının olmazsa olmazıdır.

8. Gün: Veritabanı Seçimi ve Modellemeyi Nasıl Yapmalıyız?

Full stack geliştirici yolculuğumuzun 8. gününde, uygulamalarımızın belkemiği olan veritabanlarına derinlemesine bakıyoruz. Veritabanları, uygulamalarımızın tüm verilerini (kullanıcı bilgileri, ürünler, siparişler, ayarlar vb.) depoladığı ve gerektiğinde hızlıca erişebildiği yerlerdir. Doğru veritabanı seçimi ve etkili bir veri modelleme, uygulamanızın performansı, ölçeklenebilirliği ve bakımı üzerinde doğrudan bir etkiye sahiptir. Genel olarak, iki ana veritabanı türüyle karşılaşırız: İlişkisel Veritabanları (SQL) ve İlişkisel Olmayan Veritabanları (NoSQL). Her ikisinin de kendine özgü avantajları ve dezavantajları vardır ve seçim, projenin özel gereksinimlerine bağlıdır.

İlişkisel Veritabanları (SQL) ve Modellemeleri Nelerdir?

İlişkisel veritabanları, verileri tablolar halinde organize eder ve bu tablolar arasındaki ilişkileri tanımlamak için anahtarları kullanır. PostgreSQL, MySQL, SQL Server gibi popüler veritabanları bu kategoriye girer. SQL veritabanları, veri bütünlüğünü (data integrity) ve tutarlılığını (consistency) sağlamada mükemmeldir, bu da bankacılık veya e-ticaret gibi işlemlerin kritik olduğu uygulamalar için idealdir. Veri modellemesi yaparken, "varlık-ilişki diyagramları" (ERD - Entity-Relationship Diagram) oluşturarak başlarız. Bu diyagramlar, veritabanımızdaki tabloları (varlıkları), bu tabloların sütunlarını (niteliklerini) ve tablolar arasındaki ilişkileri (bire-bir, bire-çok, çoka-çok) görselleştirir. Örneğin, bir e-ticaret uygulamasında "Kullanıcılar" tablosu ile "Siparişler" tablosu arasında "bire-çok" bir ilişki olabilir, çünkü bir kullanıcı birden fazla sipariş verebilirken, her sipariş yalnızca bir kullanıcıya aittir.

SQL kullanarak bir tablo oluşturma örneği:


CREATE TABLE Users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE Orders (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL REFERENCES Users(id),
    order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    total_amount DECIMAL(10, 2) NOT NULL,
    status VARCHAR(50) DEFAULT 'Pending'
);
    

Bu örnekte, Users ve Orders tabloları arasında user_id üzerinden bir ilişki kurulmuştur. SERIAL PRIMARY KEY otomatik artan benzersiz bir anahtar sağlarken, REFERENCES Users(id) ifadesi Orders tablosundaki user_id sütununun Users tablosundaki bir id ile ilişkilendirildiğini gösterir, böylece referans bütünlüğü sağlanır. ORM (Object-Relational Mapping) araçları (örneğin Node.js için Sequelize veya TypeORM), uygulama kodumuzdaki nesneleri veritabanı tablolarıyla eşleştirerek SQL sorgularını manuel olarak yazma ihtiyacını azaltır, geliştirme sürecini hızlandırır.

İlişkisel Olmayan Veritabanları (NoSQL) ve Kullanım Alanları Nelerdir?

NoSQL veritabanları, ilişkisel veritabanlarının aksine, verileri genellikle şemasız (schemaless) veya esnek şemalı bir yapıda depolar. MongoDB (belge tabanlı), Cassandra (sütun tabanlı), Redis (anahtar-değer) ve Neo4j (graf tabanlı) gibi çeşitleri vardır. NoSQL veritabanları, özellikle büyük veri hacimleri, yüksek ölçeklenebilirlik gereksinimleri ve hızlı veri erişimi gerektiren durumlarda tercih edilir. İlişkisel veri modelinin kısıtlayıcı olabileceği veya verinin yapısının sıkça değiştiği projelerde de avantaj sağlarlar. Örneğin, bir blog sitesindeki yorumlar veya sosyal medya gönderileri gibi yapısal olarak değişken olabilecek veriler için MongoDB gibi belge tabanlı bir veritabanı uygun olabilir.

MongoDB'de bir belge (document) örneği:


db.products.insertOne({
    name: "Akıllı Telefon X",
    brand: "TechCorp",
    price: 999.99,
    description: "Yüksek performanslı akıllı telefon.",
    specs: {
        cpu: "A15 Bionic",
        ram: "6GB",
        storage: ["128GB", "256GB"]
    },
    reviews: [
        { user: "ali", rating: 5, comment: "Harika bir telefon!" },
        { user: "ayse", rating: 4, comment: "Pil ömrü biraz daha iyi olabilirdi." }
    ]
});
    

Bu örnekte, bir ürün belgesi içinde markayı, fiyatı, açıklamayı ve hatta alt belgeler (specs) ve diziler (reviews) halinde diğer verileri nasıl depolayabileceğinizi görebilirsiniz. Bu esneklik, karmaşık ve iç içe geçmiş veri yapılarını doğrudan veritabanında saklamanıza olanak tanır. NoSQL veritabanları genellikle "eventual consistency" (nihai tutarlılık) ilkesini benimser, bu da veri yazıldıktan sonra anında tüm kopyalarında güncellenmeyebileceği anlamına gelir, ancak sonunda tutarlı hale gelecektir. Bu durum, veri tutarlılığının anlık olmamasının kabul edilebilir olduğu senaryolarda performans avantajı sağlar.

Uzman İpucu: Veritabanı seçiminizi yaparken, projenizin mevcut ve gelecekteki veri modelleme ihtiyaçlarını, ölçeklenebilirlik hedeflerini ve ekibinizin teknoloji bilgisini dikkate alın. "Tek boyut herkese uymaz" kuralı, veritabanı seçiminde de geçerlidir.

Sonuç olarak, veritabanı seçimi ve modellemesi, uygulamanızın temellerini atarken verilen en kritik kararlardan biridir. Her iki veritabanı türünün de kendi kullanım alanları ve güçlü yönleri vardır. Tam bir full stack geliştirici olmak için hem SQL hem de NoSQL veritabanlarının temel prensiplerini ve kullanım senaryolarını anlamak esastır. Hangi veritabanı modelini seçerseniz seçin, verilerinizin düzenli, güvenli ve verimli bir şekilde depolandığından emin olmak için dikkatli bir planlama ve tasarım şarttır.

9. Gün: Backend ve Frontend Arasındaki Köprü: Asenkron Veri Akışı Nasıl Sağlanır?

Full stack geliştirici yolculuğumuzun 9. gününe geldiğimizde, frontend ve backend'i birbirine bağlamanın en kritik yönlerinden birine odaklanıyoruz: asenkron veri akışı. Modern web uygulamaları, kullanıcıya kesintisiz bir deneyim sunmak için arka planda veri alışverişi yapmalıdır. Bu, bir kullanıcının sayfayı yeniden yüklemeden yeni içerik görmesi, form göndermesi veya verileri güncellemesi anlamına gelir. JavaScript'in asenkron doğası ve Fetch API veya Axios gibi kütüphaneler, bu iletişimi yönetmek için ana araçlarımızdır. Bu gün, veritabanı ve API bilgilerimizi birleştirerek, frontend'in backend ile nasıl verimli bir şekilde iletişim kurduğunu derinlemesine inceleyeceğiz.

Tarayıcıda, backend API'lerine istek göndermek için genellikle Fetch API'ı kullanırız. Fetch API, ağ istekleri yapmak için modern ve güçlü bir arayüzdür. Promise tabanlı çalışır, bu da asenkron işlemlerin sonuçlarını daha yönetilebilir bir şekilde ele almamızı sağlar. Bir örnekle açıklayalım: Bir uygulamada tüm ürünleri listelemek istediğimizde, frontend'den backend'deki /api/products endpoint'ine bir GET isteği göndeririz. Bu istek, sayfanın yüklenmesini engellemeden (non-blocking) arka planda çalışır.


async function fetchProducts() {
    try {
        const response = await fetch('/api/products'); // API'ye GET isteği gönder
        if (!response.ok) {
            throw new Error(HTTP hata kodu: ${response.status});
        }
        const products = await response.json(); // Yanıtı JSON olarak ayrıştır
        console.log('Ürünler:', products);
        // Ürünleri UI'da göstermek için gerekli işlemler...
    } catch (error) {
        console.error('Ürünler çekilirken bir hata oluştu:', error);
    }
}

fetchProducts();
    

Yukarıdaki kod bloğunda, async/await yapısını kullanarak Fetch API ile bir GET isteği gönderiyoruz. await anahtar kelimesi, Promise'in çözülmesini beklerken kodun yürütülmesini duraklatır, bu da asenkron kodu senkron gibi okumamızı sağlar. Bu yapı, hem daha temiz kod yazmamızı sağlar hem de hataları try...catch blokları ile daha etkili bir şekilde yönetmemize olanak tanır. Eğer bir POST isteği ile yeni bir veri (örneğin bir ürün) göndermek isteseydik, isteğimize bir body ve uygun Content-Type başlığı eklememiz gerekirdi:


async function addProduct(productData) {
    try {
        const response = await fetch('/api/products', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json' // Gönderilen verinin türünü belirtiyoruz
            },
            body: JSON.stringify(productData) // JavaScript nesnesini JSON string'ine dönüştürüyoruz
        });
        if (!response.ok) {
            throw new Error(HTTP hata kodu: ${response.status});
        }
        const newProduct = await response.json();
        console.log('Yeni ürün eklendi:', newProduct);
    } catch (error) {
        console.error('Ürün eklenirken bir hata oluştu:', error);
    }
}

addProduct({ name: 'Akıllı Saat', price: 199.99 });
    

Burada method: 'POST' ile bir POST isteği yapıldığını belirtiyor, headers içinde verinin JSON formatında olduğunu söylüyor ve body içinde gönderilecek veriyi JSON.stringify ile dönüştürüyoruz. Bu, frontend ve backend arasında standart ve güvenli bir veri alışverişi sağlar. Hata yönetimi, asenkron işlemlerde hayati öneme sahiptir. Ağ hataları, sunucu hataları veya geçersiz yanıtlar gibi durumlarla karşılaşabiliriz. Bu yüzden her zaman try...catch bloklarını kullanmak veya Promise zincirlerinde .catch() metodunu uygulamak önemlidir. Kullanıcıya net geri bildirimler sağlamak (örneğin bir yükleme göstergesi veya hata mesajı), kullanıcı deneyimini önemli ölçüde iyileştirir.

Uzman İpucu: Frontend uygulamanızda çok sayıda API çağrısı yapıyorsanız, bu istekleri önbelleğe almak (caching) veya veri çekme kütüphaneleri (örneğin React Query, SWR) kullanmak, hem performansı artırır hem de geliştirme sürecini basitleştirir.

Son olarak, güvenlik de bu köprünün sağlam olmasını gerektirir. Backend'den gelen verileri frontend'de doğrudan HTML olarak göstermemek (XSS saldırılarını önlemek için), kullanıcı girişi verilerini backend'e göndermeden önce ön tarafta temel doğrulamaları yapmak ve hassas bilgileri (şifreler gibi) güvenli bir şekilde aktarmak (HTTPS kullanarak), bir full stack geliştiricinin dikkat etmesi gereken önemli noktalardır. Bu gün, backend ile frontend arasındaki bu kritik iletişimin temellerini atmış olduk. Bu beceriler, dinamik ve etkileşimli modern web uygulamaları oluşturmak için vazgeçilmezdir ve full stack geliştirici olarak sizi daha da güçlü kılar.

Gerçek Bir Senaryo: E-ticaret Uygulamasında Sipariş Takibi Nasıl Çalışır?

Şimdiye kadar öğrendiğimiz tüm kavramları bir araya getirerek, gerçek dünya bir senaryo üzerinden bir full stack geliştiricinin nasıl düşündüğünü ve çalıştığını inceleyelim: Bir e-ticaret uygulamasında "Sipariş Takibi" özelliği. Bu özellik, kullanıcının geçmiş siparişlerini görmesini ve mevcut siparişlerinin durumunu takip etmesini sağlar. Bu senaryo, frontend, backend ve veritabanı arasındaki etkileşimi mükemmel bir şekilde örnekler.

1. Kullanıcı Arayüzü (Frontend - 6. Gün bilgisi):

Kullanıcı, e-ticaret sitesine giriş yapar ve "Siparişlerim" sayfasına gider. Bu sayfa, kullanıcıya geçmiş tüm siparişlerini listeleyen bir arayüz sunar. Her sipariş için bir kart veya satır olabilir, üzerinde sipariş numarası, tarihi, toplam tutarı ve mevcut durumu (örneğin "Hazırlanıyor", "Kargoda", "Teslim Edildi") gibi bilgiler yer alır. Frontend geliştirici, React veya Vue gibi bir kütüphane kullanarak bu dinamik listeyi oluşturur. Örneğin, her sipariş kartı, sipariş durumuna göre farklı renklerde veya ikonlarla görselleştirilebilir. Bu, kullanıcı deneyimini zenginleştirir ve sipariş durumunu tek bakışta anlamayı kolaylaştırır. Mobil cihazlar için bu liste, küçük ekranlarda bile okunabilir ve etkileşimli olacak şekilde duyarlı tasarıma sahip olmalıdır.


// React Bileşeni Örneği (Sipariş Listesi)
function OrderList({ userId }) {
    const [orders, setOrders] = React.useState([]);
    const [loading, setLoading] = React.useState(true);
    const [error, setError] = React.useState(null);

    React.useEffect(() => {
        async function fetchUserOrders() {
            try {
                // Backend API'sine istek gönderiyoruz
                const response = await fetch(/api/users/${userId}/orders);
                if (!response.ok) {
                    throw new Error(API hatası: ${response.status});
                }
                const data = await response.json();
                setOrders(data);
            } catch (err) {
                setError(err.message);
            } finally {
                setLoading(false);
            }
        }
        fetchUserOrders();
    }, [userId]); // userId değiştiğinde tekrar çek

    if (loading) return 

Siparişler yükleniyor...

; if (error) return

Hata: {error}

; if (orders.length === 0) return

Henüz bir siparişiniz bulunmamaktadır.

; return (

Siparişlerim

    {orders.map(order => (
  • Sipariş No: {order.orderNumber}

    Tarih: {new Date(order.orderDate).toLocaleDateString()}

    Durum: {order.status}

    Toplam: {order.totalAmount} TL

  • ))}
); }

2. API ve Backend (7. Gün bilgisi):

Frontend'den gelen /api/users/{userId}/orders isteği, backend'deki bir Express.js rotası tarafından karşılanır. Bu rota, kullanıcı kimliğini (userId) alır ve bu kimliğe ait tüm siparişleri veritabanından sorgular. Backend API'si, gelen isteği işlerken, kullanıcının gerçekten o siparişlere erişme yetkisi olup olmadığını da kontrol etmelidir (yetkilendirme). Bu kontrol, genellikle kullanıcı oturum bilgileri veya JWT tokenları üzerinden yapılır. API, veritabanından aldığı sipariş verilerini JSON formatında frontend'e geri döndürür.


// Express.js Rotası Örneği (Backend)
app.get('/api/users/:userId/orders', async (req, res) => {
    const userId = req.params.userId;
    // Güvenlik: Kullanıcının kendi siparişlerini çektiğinden emin olun
    // (Gerçek bir uygulamada, req.user.id ile userId'ı karşılaştırırdık)

    try {
        const orders = await db.collection('orders').find({ userId: userId }).toArray();
        res.status(200).json(orders);
    } catch (error) {
        console.error('Siparişler çekilirken hata:', error);
        res.status(500).json({ message: 'Sunucu hatası' });
    }
});
    

3. Veritabanı Etkileşimi (8. Gün bilgisi):

Backend, aldığı userId ile veritabanına bir sorgu gönderir. Eğer bir MongoDB kullanıyorsak, orders koleksiyonunda userId alanı belirli bir değere eşit olan belgeleri ararız. Eğer bir PostgreSQL gibi ilişkisel veritabanı kullanıyorsak, Orders tablosunda user_id sütunu belirli bir değere eşit olan satırları sorgularız. Bu sorgu, veritabanı tarafından hızlıca işlenir ve ilgili sipariş kayıtları backend'e geri döner.


// MongoDB Sorgu Örneği
// db.collection('orders').find({ userId: userId }).toArray();

// PostgreSQL Sorgu Örneği (ORM kullanmadan)
// SELECT * FROM Orders WHERE user_id = :userId;
    

Bu senaryoda, frontend kullanıcının gözünden uygulamanın görsel ve etkileşimli kısmını oluştururken, backend iş mantığını (veriyi al, işle, doğrula) yürütür ve veritabanı da tüm bilgiyi güvenli bir şekilde depolar ve erişilebilir kılar. Bu üç katman, asenkron iletişim sayesinde birlikte sorunsuz bir şekilde çalışarak kullanıcıya zengin ve işlevsel bir sipariş takip deneyimi sunar. Bir full stack geliştirici olarak, bu etkileşimlerin her bir adımını anlamak ve yönetmek, başarılı uygulamalar geliştirmek için kritik öneme sahiptir.

İleri Düzey Full Stack İpuçları: Performans ve Güvenlik İçin Nelere Dikkat Edilmeli?

Full stack geliştirici olma yolculuğunuzda temelleri attıktan sonra, uygulamalarınızı daha sağlam ve etkili hale getirmek için ileri düzey performans ve güvenlik konularına eğilmek çok önemlidir. Bir uygulamanın hızlı çalışması ve kötü niyetli saldırılara karşı dirençli olması, kullanıcı memnuniyeti ve iş sürekliliği için hayati öneme sahiptir. Bu bölümde, bu kritik alanlarda size yol gösterecek bazı ipuçlarını ve püf noktalarını ele alacağız.

Performans İpuçları:

  • Frontend Optimizasyonu:
    • Görsel Optimizasyonu: WebP veya AVIF gibi modern formatlar kullanarak görsellerin boyutunu küçültün ve lazy loading (tembel yükleme) uygulayarak sadece ekranda görünen görselleri yükleyin.
    • Kod Bölme (Code Splitting): Büyük JavaScript bundle'larını daha küçük parçalara ayırarak, kullanıcının sadece ihtiyacı olan kodu indirmesini sağlayın. Bu, ilk yükleme süresini önemli ölçüde kısaltır.
    • CSS ve JavaScript Minifikasyonu/Sıkıştırması: Üretim ortamında CSS ve JavaScript dosyalarını minifiye ederek ve Gzip/Brotli gibi algoritmalarla sıkıştırarak boyutlarını azaltın.
    • Önbellekleme (Caching): Statik dosyaları (CSS, JS, görseller) tarayıcı önbelleğinde saklayarak, sonraki ziyaretlerde daha hızlı yüklenmeyi sağlayın. Service Worker'lar ile daha gelişmiş çevrimdışı önbellekleme de mümkündür.
  • Backend Optimizasyonu:
    • Veritabanı İndeksleri: Sıkça sorgulanan sütunlara indeks ekleyerek veritabanı sorgularını hızlandırın. Yanlış indeksleme performansı düşürebileceği için dikkatli olun.
    • Veritabanı Sorgularını Optimize Etme: N+1 sorgu problemini önleyin, gereksiz JOIN'lerden kaçının ve sadece ihtiyacınız olan veriyi çekin. ORM kullanıyorsanız, sorguları gözden geçirin.
    • Bellek İçi Önbellekleme (In-memory Caching): Sık erişilen ama nadiren değişen verileri Redis veya Memcached gibi bellek içi önbelleklerde saklayarak veritabanına olan yükü azaltın ve yanıt sürelerini hızlandırın.
    • Asenkron İşlem Kuyrukları: Uzun süren veya zaman alıcı işlemleri (örneğin e-posta gönderme, resim işleme) ayrı bir işlem kuyruğuna (örneğin RabbitMQ, Kafka) atayarak ana uygulamanızın yanıt verme yeteneğini koruyun.

Güvenlik İpuçları:

  • Giriş Doğrulaması ve Sanitasyon (Validation & Sanitization):
    • Tüm kullanıcı girişlerini hem frontend hem de backend'de doğrulayın ve zararlı karakterlerden temizleyin. Bu, SQL Enjeksiyonu, XSS (Cross-Site Scripting) gibi saldırıları önler.
  • Kimlik Doğrulama ve Yetkilendirme (Authentication & Authorization):
    • Parolaları düz metin olarak değil, güvenli hash algoritmaları (bcrypt gibi) kullanarak depolayın ve tuzlama (salting) ekleyin.
    • JWT (JSON Web Tokens) veya oturum tabanlı kimlik doğrulama mekanizmalarını doğru bir şekilde uygulayın. Yetkilendirme için her isteğin ilgili kaynağa erişim yetkisinin olup olmadığını kontrol edin.
  • HTTPS Kullanımı:
    • Tüm iletişimi HTTPS üzerinden şifreleyin. Bu, man-in-the-middle saldırılarını önler ve verilerin güvenli bir şekilde aktarılmasını sağlar.
  • Güvenlik Başlıkları:
    • HTTP güvenlik başlıklarını (örneğin Content-Security-Policy, X-Frame-Options, X-XSS-Protection) doğru bir şekilde yapılandırarak çeşitli web güvenlik açıklarına karşı koruma sağlayın.
  • API Güvenliği:
    • Rate limiting (oran sınırlama) uygulayarak API'lerinizi brute-force saldırılarından koruyun.
    • Her API çağrısı için yetkilendirme kontrolü yapın.
  • Güncel Kalın:
    • Kullandığınız tüm kütüphane ve çerçeveleri düzenli olarak güncelleyin. Eski sürümlerde bilinen güvenlik açıkları olabilir.
Uzman İpucu: Uygulamanızı yayınlamadan önce mutlaka güvenlik denetimleri (penetration testing) yapın veya otomatik güvenlik tarayıcıları kullanın. Güvenlik, sonradan eklenecek bir özellik değil, tasarımın en başından itibaren düşünülmesi gereken bir unsurdur.

Performans ve güvenlik, bir full stack geliştiricinin sürekli olarak üzerinde çalışması gereken alanlardır. Bu ipuçlarını uygulayarak, sadece çalışan değil, aynı zamanda hızlı, güvenli ve ölçeklenebilir uygulamalar geliştirebilirsiniz.

Sonuç: Full Stack Geliştirici Olma Yolunda Atılan Adımlar ve Sıkça Sorulan Sorular

Full stack geliştirici olma yolculuğumuzun 6, 7, 8 ve 9. günlerini geride bırakırken, önemli ve kritik konulara değindik. Bu dört gün boyunca frontend'de kullanıcı deneyimi optimizasyonundan mobil uyumluluğa, backend'de API mimarileri ve RESTful servislerin temellerinden veritabanı seçimi ve modellemesine kadar geniş bir yelpazeyi kapsayan bilgiler edindik. Ayrıca, frontend ve backend arasında asenkron veri akışının nasıl sağlandığını öğrendik ve gerçek bir e-ticaret senaryosu üzerinden bu bilgileri nasıl birleştireceğimizi gördük. Son olarak, uygulamalarımızın performansını ve güvenliğini artırmak için ileri düzey ipuçlarına göz attık.

Bu günler, full stack geliştirme sürecinin temel taşlarını oluşturan, birbirine entegre ve dinamik parçaları anlamak adına çok değerliydi. Frontend, kullanıcının gördüğü ve etkileşimde bulunduğu arayüzü inşa ederken, backend iş mantığını ve veri yönetimini sağlar. Veritabanları ise bu verilerin kalıcı olarak depolandığı ve organize edildiği yerdir. Bu üç katmanın birbiriyle uyumlu ve verimli çalışması, başarılı bir full stack uygulamasının anahtarıdır. Unutmayın, full stack geliştirme sürekli bir öğrenme ve adaptasyon sürecidir. Teknolojiler sürekli gelişiyor, bu yüzden kendinizi güncel tutmak ve yeni araçları, metodolojileri öğrenmeye açık olmak çok önemlidir. Yolculuğunuzun bu aşamasında edindiğiniz bilgiler, gelecekteki projeleriniz için sağlam bir temel oluşturacaktır. Azimle devam edin, çünkü her kod satırı sizi hedefinize bir adım daha yaklaştırıyor!

Sıkça Sorulan Sorular

1. Full stack geliştirici olmak için hangi veritabanını öğrenmeliyim, SQL mi NoSQL mi?
Cevap: Her ikisini de öğrenmeniz uzun vadede faydalıdır. SQL (PostgreSQL, MySQL) veri bütünlüğünün kritik olduğu projeler için vazgeçilmezken, NoSQL (MongoDB, Redis) yüksek ölçeklenebilirlik ve esnek veri yapıları gerektiren projelerde avantaj sağlar. Temel olarak bir SQL ve bir NoSQL veritabanına hakim olmanız, projenin ihtiyaçlarına göre doğru kararı vermenizi kolaylaştıracaktır.
2. Frontend ve backend arasında hangi veri formatını kullanmalıyım?
Cevap: JSON (JavaScript Object Notation) formatı, hafifliği, okunabilirliği ve JavaScript ile doğrudan entegrasyonu sayesinde frontend ve backend arasındaki veri alışverişi için en yaygın ve tercih edilen formattır. GraphQL gibi alternatifler de belirli senaryolarda kullanılabilir, ancak JSON endüstri standardıdır.
3. API güvenliğini sağlamak için ilk adım ne olmalı?
Cevap: İlk ve en önemli adım, tüm API uç noktaları için kimlik doğrulama (authentication) ve yetkilendirme (authorization) mekanizmalarını doğru bir şekilde uygulamaktır. Kullanıcıların yalnızca yetkili oldukları verilere erişebildiğinden emin olun ve hassas verilerin HTTPS üzerinden şifrelenmiş olarak aktarıldığından emin olun.
4. Mobil uyumlu tasarım yaparken nelere dikkat etmeliyim?
Cevap: Mobil uyumlu tasarımda öncelikle "mobil öncelikli" (mobile-first) yaklaşımı benimseyin. Esnek düzenler için CSS Flexbox ve Grid kullanın. Görselleri optimize edin ve duyarlı görsel tekniklerini (srcset, sizes) kullanın. Etkileşim alanlarının (butonlar, linkler) dokunmatik ekranlar için yeterince büyük olduğundan emin olun.
5. Full stack geliştirici olarak performansı artırmak için en etkili yol nedir?
Cevap: Performans optimizasyonu genellikle birden fazla alanı kapsar. En etkili yollardan bazıları:
  • Kritik render yolunu optimize ederek ilk yükleme süresini kısaltmak (CSS ve JS'i optimize etmek).
  • Veritabanı sorgularını ve indekslerini optimize ederek backend yanıt sürelerini düşürmek.
  • Sıkça erişilen verileri önbelleğe almak (hem frontend'de hem de backend'de).
  • Görselleri ve diğer medya dosyalarını optimize etmek.

Performans sorunlarını tespit etmek için tarayıcıların geliştirici araçlarındaki "Performance" ve "Network" sekmelerini aktif olarak kullanın.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.
Mobil sürümden çık