Hepsiburada Micro Frontends Dönüşümü

Oğuzhan Aslan
Jan 8, 2020 · 12 min read

Nedir Bu Micro Frontends?

Bu yazıda, son zamanlarda oldukça gündeme gelen Micro Frontends mimarisinin ne olduğunu, neden ortaya çıktığını ne gibi problemleri çözüp, ne tür problemler yaratabileceğini ve Hepsiburada’da başladığımız dönüşüm deneyimlerini kendi yorumumla anlatmaya çalışacağım.

Image for post
Image for post

Web uygulamaları için konuşacak olursak, Frontend uygulamaları gün geçtikçe büyüyor ve backend’den daha fazla görev çalmaya devam ediyor. Geliştirme teknikleri ve frameworkler zaman içerisinde çok değişim gösterdi. JQuery, Backbone, Angular 1.x, Grunt, Gulp konuşurken, hayatımıza Webpack, Babel, React, Flux, Redux, Vue vs. gibi araçlar/kütüphaneler girdi ve yenileri girmeye devam ediyor. Linter, Server Side Rendering, Client Side Rendering, PWA, Storybook diye devam ettirebileceğim bu terimler, ilk bakışta Frontend geliştirme yapmayan geliştiricilere çok karışık görünüyor.

Micro Frontends Nedir?

Micro Frontends ile bir karmaşıklık daha ekleniyor gibi görünse de, bu mimari büyük projelerin ve büyük ekiplerin yaşadığı problemleri çözmeyi öneren ve görece karmaşıklığı azaltmaya çalışan bir mimari.

Hepsiburada olarak biz de Micro Frontends mimarisine geçmeye karar verdik ve anasayfamızı yenilerken bu mimariyi gözeterek geliştirme yaptık. Hem bu mimarinin tam olarak ne olduğunu, hem de Hepsiburada’da başladığımız bu dönüşümde edindiğimiz tecrübeleri paylaşacağım.

Image for post
Image for post
Görsel: 1

Kimler Kullanıyor ?

Micro Frontends; Spotify, Dazn, OpenTable, Ikea, Skyscanner ve Zalando gibi bazı büyük şirketler tarafından farklı teknikler ile birlikte kullanılıyor. Bu teknikleri yazının devamında daha detaylı öğreneceğiz.

Spotify bu mimariyi Iframe ile birlikte, Ikea Edge Side Includes, OpenTable ve Skyscanner OpenComponents ile birlikte geliştirmiş.

Sorunlarımız ?

Hepsiburada Arge organizasyonunda, yaklaşık 17 tane Yazılım ekibi bulunuyor. Bu ekiplerin içerisinde Frontend, Backend, Full Stack, DevOps, QA, Business Analyst gibi alanlarda uzmanlaşmış insanlar bulunuyor. Bunların 12 tanesi direkt sitenin ön yüzü ile etkileşim halinde.

Ve bu ekiplerin her biri, yazılım operasyonunun farklı ekranlarından/görevlerinden sorumlu. Her ekibin, müşteri için değer sağladığı kendi uzmanlık alanları bulunuyor.

Frontend gözüyle bakacak olursak, Checkout ekibinin sorumluluğu sadece Sepet ve Ödeme Ekranları ile sınırlıyken, OMS ekibi sitenin Siparişlerim ekranından sorumlu.

Kullanıcılar Hepsiburada’da gezinirken aslında her sayfa geçişinde başka bir uygulamayı ziyaret ediyor.

Bu tarz bir organizasyonda, X ekibi ASP.Net projesinde TypeScript ve SCSS ile Header geliştirirken, Y ekibi aynı arayüzü Java ve Native CSS ile, Z ekibi ise React ve Styled Component ile geliştirebiliyor. Bu ekipler birbirlerinden bağımsız bir şekilde geliştirme yapıyorlar.

Image for post
Image for post
Görsel: 2- Micro Frontends geçişi öncesi de, Hepsiburada’da her ekip kendi sorumluluğundaki sayfalarda Frontend geliştirmesi yapıyordu.

Peki ne tarz problemler yaşıyoruz?

Neden ve Nasıl? 🎉

Micro Frontends, birçok ekibin aynı anda büyük ve karmaşık bir ürün üzerinde çalışabilmesi için, frontend monolitlerini daha küçük, daha yönetilebilir parçalara ayırıyor.

Bu küçük uygulamalar, daha sonra bir araya gelip, aynı ekranda kullanıcıya sunuluyor. Aslında yıllar önce sıklıkla kullandığımız Iframe teknolojisinden çok farklı değil.

Farklı ekiplerin geliştirdiği frontend uygulamaları, tek bir sayfada bir araya geliyor. Nasıl bir araya gelip, birbirleriyle iletişime geçecekleri ise işin başka bir boyutu. Bu mimarinin en büyük amaçlarından biri, frontend üzerinde çalışan büyük ekiplerin verimliliğini arttırmak.

Image for post
Image for post
Görsel: 3

Micro Frontends’in en önemli faydalardan bazıları şunlar:

Özellikle birden fazla küçük uygulamanın olması, olası bir refactoring ve sıfırdan yazma sürecini oldukça kolaylaştırıyor. Aynı zamanda otonom takımlara büyük bir esneklik sağlıyor.

Eğer genelleme yapacak olursam, biz geliştiriciler elimizden geldiğince eski diyebileceğimiz teknoloji ile yazılmış legacy projelerden uzak durmaya çalışır ve olabildiğince yeni teknolojilerin kullanıldığı geliştirme ortamlarında çalışmak isteriz. Legacy kodu ortadan kaldırıp yeniden yazmak genelde maliyetli bir iştir.

Ama legacy proje üzerinde bulunan küçük bir parçayı, Fragment olarak geliştirip dışarıya sunmak o kadar maliyetli bir iş değil. Bu sayede legacy projelerin sorumluluklarını yavaş yavaş küçültebiliyorsunuz. Aynı zamanda dönüştürdüğünüz kısmı, her yerde kullanabilir hale getirmiş oluyorsunuz.

Bağımlılık Yönetimi ☠️

Hepimizin çok duyduğu bir deyim vardır ‘yok öyle üç kuruşa beş köfte’ diye. Bu deyimi burada kullanmadan edemeyeceğim. Bu mimaride kaçınılmaz olarak yaşanacak olan aynı bağımlılıkları tekrar tarayıcıya yükletmek ve yüklenen bağımlılıkların birbirleri arasındaki uyumu takip etmek çok büyük bir maliyet.

Örneğin, Comment uygulaması React 16.x ve Redux 4.x, Product Filter uygulaması React 15.x ve Redux 3.x versiyonlarını kullanıyorsa aynı bağımlılıkları kullanıcıya tekrar tekrar yükletmiş olacağız. JavaScript bundle boyutlarımız olması gerekenden fazla olacak. Peki bu konuda bir best practices var mı?

Image for post
Image for post
Güzel soru.

Birden fazla versiyon mu yükleteceğiz? Birden fazla app’i bir sayfada çalıştırdığımızda uyumlu çalışacak mı? Script Loading ve Script Execute yüzünden uygulamamız yavaşlayacaksa ne anlamı var? Kafada yüzlerce soru işareti oluşturuyor değil mi?

Neler yapılabilir?

Microfrontends mimarisinde en iyi çözüm, kendi bulduğunuz çözümünüz oluyor. Bu tarz problemleri nasıl çözeceğiniz size kalmış bir durum. Örnek projelere baktığınızda birbirinden farklı uygulamalar olduğunu görebileceksiniz.

Nasıl Çözdük?

Biz bu sorunu, ortak kullandığımız kütüphaneler için bir uygulama geliştirerek çözmeye çalıştık. Bu uygulamanın tek görevi ortak kullanılan kütüphaneleri bir araya getirip bir bundle oluşturmak.

Bu sayede her ekip aynı kütüphanenin versiyonlarını kullanıyor. Böylece tarayıcılara aynı kütüphaneyi birden fazla yüklememiş oluyoruz.

JavaScript tarafında çok fazla conflict yaşanmasa da CSS tarafında yaşanabiliyor.

Image for post
Image for post
Görsel: 5

Bu durumda, her fragment aynı CSS selector’unü kullanırsa çatışmalar olur. Her ekibin, “global variable” seçip, kendi içinde bir scope sağlamak bu problemi ortadan kaldıracaktır. Global olması gereken CSS selector’leri, Font’lar veya Global JS değişkenlerini servis edebileceğiniz bir fragment tasarlayabilirsiniz. Her ekip geliştirmesini oradan yapabilir.

Image for post
Image for post
Görsel: 6

Otonom Takımlar ve Bağımsız Deploymentlar

Mikroservisler de olduğu gibi, bu mimaride birbirinden bağımsız Frontend uygulamalarının kullanılabilmesi çok önemli.

Image for post
Image for post
Görsel: 7

Varsayalım ki, Angular veya X bir framework ile geliştirdiğimiz frontend uygulamamızın iletişime geçtiği backend servislerinin mimarisi mikroservis ile geliştirilmiş olsa bile, frontend uygulamaları monolotik bir davranış sergiliyor.

Uygulamanın herhangi bir ekranında yapacağımız küçük bir değişiklik için, deploy/release işlemlerine ihtiyaç duyuyoruz. Buraya kadar bir problem olmadığının hepimiz farkındayız.

Fakat çok farklı logiclere sahip farklı domainlerimiz, kalabalık bir development takımına sahip olduğumuzda bu frontend uygulamasının deployment ve geliştirme sürecini yönetmek biraz karmaşık ve yavaş olabiliyor.

Bu yapı ile birlikte, frontend kod tabanında çalışan kişi sayısını minimize edebiliyoruz. Ekibe sonradan katılan bir kişinin çok büyük bir yapıya giriş yapması gerekirken, bu karışık ve zor mimariyi uzun bir zaman dilimi içerisinde öğrenmesi yerine, ekibin sorumlu olduğu ve geliştirmekle yükümlü olduğu projeyi öğrenmesi yeterli olabiliyor.

Image for post
Image for post
Görsel: 8

Micro Frontends büyük bir uygulamada güzel avantajlar kazandırıyor. Uygulamanız, ekipler tarafından parçalara bölünerek herkes bir sorumluluk üstleniyor.

Büyük bir e-ticaret uygulamasını ele alacak olursak, Ödeme ekranı bambaşka logic’lere sahipken, Ürün filtreleme kısmı bambaşka bir logic’e sahip.

Genelde bu tarz uygulamalarda her ekip, uygulamanın bir ekranı ile ilgileniyor ve o domain üstünde uzmanlaşıp geliştirme yapıyorlar.

Bu mimari ile birlikte, Mikroservis mimarisinin backend’e getirdiği kazanımların büyük bir çoğunluğunu, kod tabanı genişledikçe kaosa mütevazi bir katkı sağlayacak Frontend uygulamaları içinde elde etme şansımız doğuyor. (eğer gerçekten büyük bir ekibiniz ve bahsettiğim problemleriniz varsa…)

Fragment Nedir ?

Micro Frontends mimarisinde, geliştirip dışarıya açtığımız her uygulama Fragment olarak adlandırılıyor.

Yazının öncesinde çok defa kullanadık ama, Fragment dediğimiz kavramı temel anlamda Node.js ile geliştirilmiş basit bir HTTP servisi olarak düşünebilirsiniz.

Image for post
Image for post
Görsel: 9

Geliştirdiğimiz componentlerin bir araya geldiği küçük parçalar olarak hayal edebilirsiniz. (Header, Product Slider, Product List, Popular Posts)

Nasıl Çalışmalı?

Bizim senaryomuzda Fragment’lar, HTML çıktısı ve asset dosyalarının path’lerini sunan bir HTTP servisi. Genel kullanım bu yönde.

Nasıl Bir Araya Geliyorlar?

Daha sonra bu Fragment’ları Layout Service ismini verdiğimiz bir uygulamada kullanıyoruz. Temel anlamda Layout Service katmanını, bu Fragment çıktılarının birleştiği sayfa olarak düşünebilirsiniz. Fragment çağrıldığında html, js, css çıktısını dönerken, Layout uygulaması kullandığı fragment'lara bağlanıp bunları birleştiriyor.

Image for post
Image for post
Görsel: 10

Tailor’un, Layout Service kullanımı örnek olarak bulunuyor. Burada <fragment> componenti ilgili fragment'ın yayınlandığı endpoint'e gidip çalıştırıyor.

Tabi Layout Service olarak tanımladığımız katmanı nasıl kurgulayacağınız size kalmış. Bu yöntemlerinden sadece bir tanesi. Sizin ihtiyaçlarınıza göre yöntemler üretmeniz veya daha önce kullanılmış yapılardan örnek alabilirsiniz.

Layout Services

1- Iframe

iFrame, her ne kadar çok eski bir teknoloji olsa da, eğer Arama Motoru dostu sayfalar yaratma ihtiyacınız yoksa ve uygulamalarınızı Server’da render etmiyorsanız, benim düşünceme göre başınızı çok fazla ağırtmadan kullanılabilecek en kolay yollardan birtanesi.

Iframe’ler ile birbirinden bağımsız fragment’ları kolay bir şekilde bir araya getirebilirsiniz.

Mooa kütüphanesi bu yolda ilerleyecekler için çok yardımcı olacaktır.

2-Server Side Application

Arama motorlarından yüksek trafik alan bir uygulamanız söz konusuysa, Frontend uygulamanızın SSR yaptığını veya Pre-Rendering tekniklerini muhakkak kullanıyorsunuz demektir. Zira arama motorlarının botları, JavaScript ile oluşturulmuş içerikleri hala tam sağlıklı bir şekilde okuyamıyor.

3-OpenComponents

OpenComponents, bir yöntemden daha çok açık kaynak olarak geliştirilmiş hazır bir araçtır. MicroFrontends için hemen hemen çoğu şey için çözüm sağlamakta. OpenComponents’i bir JavaScript framework’ü olarak değil, Frontend fragment’larını hızlı bir şekilde geliştirmek ve yayınlamak için geliştirilmiş bir tool veya pattern olarak tanımlıyor.

OpenComponents yapısında yarattığınız componentler fragment olarak dışarı sunuluyor. Ardından bunları OpenComponents registry’sine ekliyorsunuz.

Componentler, HTML, Javascript ve CSS’ten oluşan küçük isomorphic kod yapılarıdır. İsteğe bağlı olarak, sunucu tarafında Node.js ile birlikte render edebiliyor. Kullanmanız için hiç bir ayar yapmadan fragmentlarınızı size hazırlıyor.

Aynı zamanda esinlenebileceğiniz birçok özelliği var. Kesinlikle göz atmalısınız.

Tailor Zalando ekibi tarafından geliştirilmiş, örnek olarak görebileceğiniz açık kaynaklı bir Micro Frontends Template Engine.

https://github.com/zalando/tailor

Hepsiburada’da Neler Yaptık?

Voltran ismini verdiğimiz bir proje ile start verdiğimiz dönüşüm sürecinde, Voltran componentlarımızı(fragment) paylaşmamızı sağlayan, React ve Node.JS kullanılarak hazırlanmış bir framework.

Şirket içerisindeki ekipler, Voltran projesi Micro Frontrends fragment’larını geliştirmeye başlıyorlar.

Dependencies yönetimini ise yine bir micro frontends fragment’ı tasarlayarak çözmeyi düşündük. Bu fragment ortak olarak kullanılan tüm dependencies paketlerini birleştiriyor ve içerisinde duplicate paket olmayacak şekilde, bundle’lar oluşturuyor.

Image for post
Image for post
Görsel: 11

Her ekibin dışarıya sunduğu Voltran Fragmentları (Product List, Like Button, Auth Modal), Server tarafından render edilip output olarak HTML çıktısı veriyor veya sadece Webpack ile oluşturulmuş JavaScript bundle’ının adresini döndürüp, Client tarafında render oluyor.

Bazı sayfalarda SSR ihtiyacı varken, arama motorlarına kapalı sayfalarda SSR desteğini kaldırıyoruz. Çünkü React bu konuda oldukça yavaş ve Server tarafında render yapmak oldukça maliyetli bir iş.

Fragment’lar deploy olurken otomatik olarak versiyonlanıyorlar. Ve bu versiyonları olası bir sorunda geri dönüş yapmak için saklıyoruz. Aynı zamanda bu versiyonları bir panelden kontrol edebileceğimiz bir arayüz hazırlamayı düşünüyoruz.

Image for post
Image for post
Görsel: 12

Voltran servisi oluşturduğu tüm bundle’ları bu şekilde sunuyor.

Ardından bu HTML ve JavaScript dosyalarını Layout Engine dediğimiz katmanda çalıştırıyoruz. Biz şu an hem Legacy projelerin içinde hem de dışında bu yapıyı kullanmaya destek veriyoruz.

Layout Engine tarafında neler yaptık?

Hepsiburada’da başladığımız Micro Frontends dönüşümünde, aslında ekranlarımızın küçük bir kısmını geçirmeyi tercih ettik. Geçiş sürecini en zararsız şekilde atlatabilmek hem de daha yönetilebilir bir yapı oluşturmak için adım adım ilerlemeye özen gösterdik.

Bu geliştirme süreci içerisinde, ekip olarak hem çok şey öğrendik hem de ileride bu yapının neye evrilmesi gerektiği konusunda yeterli bir olgunluğa ulaştık.

Mosaic, OpenComponents, Podium gibi örnekler olsa da, sıfırdan oluşturacağınız yapının Legacy kodunuz ile uyumlu çalışması gerekiyor.

Bizim için fragment’ın iki anlamı var. Birincisi Server tarafında render olup HTML output veren Fragment’lar, ikincisi ise Webpack tarafından oluşturulmuş JS Bundle’ı dönen fragmentlar.

Mevcut Projelere Uyum

En önemlisi geliştirdiğimiz fragment’ları ilk aşamada, şu an ki deployment sürecimizi ve yükümüzü arttırmadan mevcut uygulamalarımızın içinde çalıştırmamız gerekiyordu.

Peki Hepsiburada Storefront uygulamaları altyapı olarak ne kullanıyordu? Bu geçişte ne tür bir altyapı hazırlamalıydık?

Image for post
Image for post
Görsel: 13

Sorumlu olduğumuz iki uygulama farklı altyapılar üstünde çalışıyor. Storefront Web olarak adlandırdığımız projesi uzun süredir geliştirilen ve Desktop görünümünde çalışan bir uygulama.

Storefront Mobile projesi adından anlaşılacağı üzere, Mobile görünümde devreye giren PWA uygulamamız.

Geliştireceğimiz Micro Frontends fragmentlarını, Isomorphic çalışan React projesinde ve ASP.Net projesinde çalıştırmamız gerekiyordu. Aynı zamanda birbirinden farklı uygulamalarda çalışan bu voltran fragment’ları, birbirleri ile iletişim halinde olmalılardı.

Bunun için, Fragment render eden bir React Componenti ve aynı işi ASP.Net tarafında yapan bir modül geliştirdik.

Componentler Arası İletişim

Componentler arası iletişimi ise Event Bus patternini kullanan bir JavaScript kütüphanesi ile sağlıyoruz. Bunun gibi farklı farklı ekiplerin kullanması gereken fonksiyonları veya değişkenleri, özel bir fragment’tan sunmayı tercih ettik.

Image for post
Image for post
Görsel: 14 — ProductList uygulaması addToCart isimli bir event ile sepet totalinin 15 olacağını bildiriyor.
Image for post
Image for post
Gösel: 15 — Sepet uygulaması ise bu event’e gelen istekleri dinliyor ve kendini state yapısını güncelleyerek görünen değeri güncelliyor.

Artılar — Dezavantajlar ve İpuçları

Örneğin storefront_displayed_modal, .checkout > .box > h3 gibi kullanımlar işinizi gerçekten kurtaracaktır.

Geri Bildirim 📭

Yazı ile ilgili tavsiye, öneri, eleştiri ve düzeltmeleri dikkate alıyorum. Geri bildirim ve iletişim için:

Image for post
Image for post

Kaynaklar:

Teşekkürler ❤

Bu süreçte yazıyı düzenlerken bana destek olan Ahmet Turan, Fatih Burak İlk, Volkan Tağal ve Yasin Uysal’a teşekkür ederim.

hepsiburadatech

hepsiburada technology

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store