(Što se dogodilo kada sam kliknuo na ovo nešto i zašto nigdje ne piše čemu to služi?)
Dokumentacija, specifikacija, …
Svi oni koji se bave razvojem aplikacija vjerojatno su se susreli s pojmovima “dokumentacija” i “funkcionalna specifikacija softvera”. U slučaju da se time bave duže vrijeme, gotovo je sigurno da su naišli i na zastarjelu funkcionalnu specifikaciju i nepotpunu dokumentaciju. Ovo je, nažalost, uobičajeni problem kod većine projekata za čiji je razvoj potrebno nešto dulje razdoblje (više od 6 mjeseci) te čije se funkcionalnosti s vremenom povećavaju i mijenjaju. Kod ovakvih projekata, dokumentacija kojom se okvirno opisuje što bi sustav trebao postati te funkcionalna specifikacija koja opisuje njegov način rada, obično nastanu na početku.
U ovom trenutku sve je u redu, naručitelj je zadovoljan jer se iz dokumentacije jasno vidi ono što želi dobiti, a u funkcionalnoj se specifikaciji nalazi točan opis očekivanog rezultata. Potom svi spomenuti dokumenti dolaze razvojnom timu koji, nakon što ih prouči, na temelju funkcionalne specifikacije počinje graditi sustav. I dalje sve ide po planu i izgleda da će se projekt realizirati u roku i na opće zadovoljstvo. No, u jednom je trenutku naručitelj poželio manju izmjenu. Uobičajeno za današnje doba kada je “in” biti agilan, analitičar odmah počinje pisati novu funkcionalnu specifikaciju i šalje je razvojnom timu koji, nakon što je primi, počinje s implementacijom. Nekoliko mjeseci i nekoliko desetaka izmjena i dodataka kasnije, sustav je konačno gotov i svi su sretni i zadovoljni – agilni razvoj djeluje, a raspisivanje dodatnih funkcionalnosti u funkcionalnim specifikacijama omogućilo je da se tim u kratkom vremenu prilagodi novim zahtjevima i napravi onakav sustav kakav je naručitelj želio, te je on pušten u produkciju. Ovaj pristup mnogi smatraju dobrim i ispravnim, no njegov je najjači argument ujedno i njegova najveća mana – dodavanjem novih funkcionalnosti kroz nove funkcionalne specifikacije uvodimo dodatnu kompleksnost u samu dokumentaciju, kao i fragmentaciju osnovnih informacija o tome što koji dio sustava zapravo radi.
Ovo može dovesti do toga da nakon nekoliko godina postoji vrlo veliki broj dokumenata koji opisuju određene dijelove sustava, no niti jedan ne opisuje sustav u cijelosti. Situacija je još gora ako određeni dokument u potpunosti ne opisuje niti dio sustava na koji se odnosi jer opisuje samo dio dijela sustava koji je izmijenjen, što je česti slučaj. U konačnici, ovo će znatno otežati razvijanje novih funkcionalnosti, a uvođenje novih članova tima bit će gotovo nemoguće temeljem dokumentacije. Osim toga, upoznavanje funkcionalnosti sustava će se s čitanja funkcionalne specifikacije prebaciti na čitanje softverskog koda da bi se doznalo kako i što koji dio sustava radi.
…samo malo, sad ću naći ispravnu verziju…
Ako se možete prepoznati u prethodno opisanoj situaciji, a želite nešto promijeniti, ono što možete napraviti je “oživjeti” svoju dokumentaciju te zamijeniti stari i “mrtvi” način pisanja dokumentacije i funkcionalnih specifikacija pisanjem žive dokumentacije. Živa dokumentacija je dokumentacija koja, za razliku od prethodno opisane, nikada neće zastarjeti niti se protezati kroz nebrojene dokumente kroz koje se potrebno probijati u potrazi za aktualnim informacijama. Ideja koja stoji iza žive dokumentacije je da se programski kod i funkcionalne specifikacija povežu na način da se izmjene u kodu, a koje utječu na funkcionalnost, automatski reflektiraju u dokumentaciji. Ovaj način dokumentiranja rezultira jednim dokumentom pomoću kojega je opisan kompletan sustav zajedno sa svim svojim funkcionalnostima. Ovakvu dokumentaciju zovemo živom dokumentacijom budući da se sa svakom izmjenom u funkcionalnoj specifikaciji i sa svakom novom funkcionalnosti koja se dodaje u sustav i sam dokument mijenja, evoluirajući zajedno sa sustavom koji opisuje.
Pisanje žive dokumentacije na prvi pogled vjerojatno zvuči kao naporan i skoro nemoguć posao koji nikada ne bi uspjeli napraviti sami. Osim toga, nije praktično pretraživati i prepravljati dokument, da ne govorimo o problemu verzioniranja. No, ako odlučite odustati od dokumentiranja funkcionalnosti sustava kroz bezbrojne funkcionalne specifikacije, postoji način da vam dokumentaciju netko, ili nešto, ‘oživi’ te da se taj dokument samostalno mijenja kroz nove verzije sustava.
… oprostite dr. Victor F., možete li mi pomoći?
Ipak, neće vam trebati pomoć dragog doktora Victora, i ne trebate se bojati da će se vaša dokumentacija pretvoriti u njegovo poznato čudovište, ali ako ne budete pažljivi, mogla bi se okrenuti protiv vas. Možete koristiti neku od postojećih metoda raspisivanja funkcionalnosti sustava pomoću kojih se može generirati živa dokumentacija te, ovisno o potrebama sustava i odabranom načinu raspisivanja funkcionalnosti, možete odabrati odgovarajući generator. Kako se u današnje doba sustav obično razvija oko njegovog API-a, kao primjer ću opisati kako napraviti živu dokumentaciju nekog API-a koristeći Swagger.
Swagger je framework za opisivanje API-a (REST servisa) običnim jezikom koji bi svi trebali razumjeti, tj. razumljiv je i ljudima i strojevima. Jednostavan je, ali u isto vrijeme i dovoljno složen da može dati uvid u kreiranje osnove sustava naručitelju, analitičarima, kao i developerima. Pritom nije komplicirani nečitljiv onima bez tehničkog znanja, a niti prejednostavan pojedincima koje zanimaju tehnički dijelovi. Za njegovo korištenje postoje dva osnovna načina, top-down i bottom-up, ali, u slučaju potrebe, mogu se i miješati. U top-down načinu najprije se definiraju funkcionalnosti sustava te se raspisuje sve ono što API treba podržavati. Osim toga, svaku se funkcionalnost može dodatno opisati raspisivanjem njenog očekivanog rezultata te primjerom tog rezultata. Dodaje se detaljan opis sustava koji se opisuje, definiraju se svi entiteti s kojima će sustav raditi i načini autorizacije, dodaju se primjeri mogućih odgovora koji se očekuju od API-a, kao i moguće greške. Ovo može biti od velike pomoći developerima jer čak i prije nego li su počeli razvijati sustav, imaju mogućnost testirati ga.
Bottom-up pristup je, kao što mu i ime kaže, potpuna suprotnost prvome. Kod bottom-up pristupa Swagger specifikacija generira se automatski prema postojećem API-u. Čim je generirana, dobiva se website koji sadrži popis svih metoda koje taj API sadrži i primjere poziva prema njima. Može sadržavati i detaljne opise svake od tih metoda. U .net-u, za automatsko generiranje Swagger dokumentacije brine se Swashbuckle. Swashbuckle se nakon dodavanja u projekt konfigurira za kreiranje Swagger definicije. Osim što za vrijeme builda generira Swagger definiciju, Swashbuckle nudi i mogućnost da se metodama dodaju opisi i primjeri koji će biti uključeni u generiranu Swagger definiciju i koji će biti vidljivi u našoj živoj dokumentaciji.
Zasada su prelaskom na živu dokumentaciju usklađeni analitičari, developeri API sustava koji se razvija te developeri aplikacije koja će konzumirati API (naručitelj, korisnici…). Svi su uključeni u raspisivanje dokumentacije. Dodatno je omogućeno da ova dva tima developera mogu neovisno razvijati svoj dio te ne moraju čekati drugi tim da završi kako bi mogli testirati svoj kod.
Sada dolazimo do dijela koji se odnosi na dodavanje nove funkcionalnosti. Tim koji razvija API dobiti će zahtjev za implementaciju nove funkcionalnosti. Čim ju implementira u API, ta funkcionalnost će biti vidljiva i u Swagger dokumentaciji. Na ovaj je način Swagger dokumentacija uvijek ažurna te stalno sadrži opise i primjere korištenja svih funkcionalnosti koje API podržava. Kako se nove funkcionalnosti dodaju, tako se automatski pojavljuju u dokumentaciji. Kako se mijenjaju, te se izmjene vide i u dokumentaciji, a ako se neka ukloni, nestane i iz dokumentacije.
Ali kako to zapravo radi?
Koristit ću osnovni primjer pomoću kojega se standardno prezentira Swagger, tj. API za potrebe dućana kućnih ljubimaca. Prema tome standardno radimo Swagger JSON ili yaml file u kojem definiramo „info“ dio s osnovnim podacima vezanim za sustav (Slika 1).
swagger: "2.0"
info:
description: "This is a sample server Petstore server."
version: "1.0.0"
title: "Swagger Petstore"
termsOfService: "http://swagger.io/terms/"
contact:
email: "apiteam@swagger.io"
license:
name: "Apache 2.0"
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
host: "petstore.swagger.io"
basePath: "/v2"