FreeVar: Difference between revisions
(One intermediate revision by the same user not shown) | |||
Line 494: | Line 494: | ||
==Server/kliendirakenduse retsesnsioon Skeddl'e== | ==Server/kliendirakenduse retsesnsioon Skeddl'e== | ||
* Üldpilt: | * Üldpilt: Kogu rakendus on jaotatud ilusti loogilisteks projektideks. Ei saa hästi aru mida teeb ClientRepo projekt solutionis. Aluseks võetud ilmselt Web & WebAPI projekt. Klasside nimetusel on osad klassid mingil põhjusel snake_case'is, tegemist pole otseselt veaga vaid stiiliprobleemiga. Alles on jäetud ka klassid mida pole vaja. Äriloogika tükke eraldi ei leia, kogu loogika laotud controlleritesse. samuti puudu service'd. | ||
Kogu rakendus on jaotatud ilusti loogilisteks projektideks. Ei saa hästi aru mida teeb ClientRepo projekt solutionis. Aluseks võetud | |||
* Serverrakendus : | * Serverrakendus : Klientrakendus kasutab serveriga suhtlemiseks serverrakendust. Serverrakenduse jaoks on eraldi olemas projekt DAL. Serverrakenduse aluseks on ilmselt võetud kliendipool kirjutatud kontrollerid ning siis kirjutatud API sisu asemele. Sellisel lähenemisel on omad kiiksud - võib tekkida olukordi, kus API teeb vähem, kui rakendus nõuab. Näiteks, kui süsteemis salvestatakse mingi kanne, mis eeldab ka mingit muud toimingut, kuid see toiming tehakse muu API päringuga. Samuti annab see märku, kuidas on andmebaas struktureeritud. Ilusti on kasutatud "Route" annotatsioone, kuid REST teenust see väga ei meenuta (sama häda ka enda projektis, kuid osades kohtades katsusin RESTi jälgida). Näiteks Subjectcontroller::GetSubjectById() võiks olla mapitud "api/Subject/{id}" vastu. Hetkel on urlis sees veel SubjectGetById, mis on sisuliselt irrelevantne. Järgnev mis silma hakkas on ka enda projektis probleemiks, kui manipuleeritakse mingit resurssi, mis on mingi resursi osa - näiteks kasutaja subjektid, siis võiks meenutada url midagi sellist: "user/{userId}/subjects". | ||
* | REST best practices: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api | ||
* Klientrakendus: Mõned actionid on muutunud üsna lohisevaks ning võiks olla eraldi klassis, mis tegeleb mingi tegevusega (TasksController::Index). On kasutatud annotatsioone(mis meetodile vastab mingi action, custom route'd). Tundub, et on olemas ka turvavead. Mitmetes actionites tehakse päringuid ainult findById() meetodit kasutades. Väga paljud controllerid on ilma authorize annotatsioonita, mis tähendab, et voli igale poole ligi saada on olemas. Oleks olnud hea ka praktiseerida role based accessi, ehk siis omistada kasutajatele rollid ning kasutada neid rolle Authorize meetodis. Hea näide turvaprobleemist on näiteks SubjectsController::Unsubscribe, õiguseid pole piiratud aga samas otsib controller User.Identity alt aktiivset kasutajat. Siinkohal siis tekib kohe nullpointer. CommentsController::deleteConfirmed on imelik, kuna leitakse mingi TaskId aga samas ei kontrollita selle põhjalt mitte midagi. On olemas ka eraldi DAL projekt, kuid halb on see, et kasutatakse samu interface'i mida kasutatakse serveri DAL osale. Enda projektis tekkis ka sama häda. Häda on selles, et meetodid on interface'is defineeritud domeenimudelitga aga need hakkavad reetma andmebaasi struktuuri. Sestap peaks kasutama erinevates DAL projektides erinevaid interface'i. Siis saaks kasutada ka DTO'sid andmete postitamisel kui ka lugemisel. Minu arvamus API'dest on see, et tagastada võiks enamat, kui lihtsalt bool'i või tühja returni. Eriti halb olukord tekib näiteks UserSubjectRepository::SubscribeUser'i meetodis kus return on sama, kuigi kontroll on staatus koodi jaoks olemas. | |||
* Kokkuvõte: Arvan, et autorid on teinud hea töö ning mõistavad, kuidas koostada API teenust. |
Latest revision as of 17:56, 4 June 2016
Tiim
- Mihkel Viilveer
- Kristjan Adrat
- <sinu_nimi>
- <sinu_nimi>
Blogi
- 08.03 - Tiimi loomine.
- 12.03 - Wiki skeleton. VSO projekti ja GIT repo loomine.
- 13.03 - Valmisid XML, XSD, XSLT failid
- 22.03 - Idee esimene draft. Taskbreakdown v0.1
- 27.03 - XML Retsensioonid. Taskbreakdown v0.2
Projekti esitus
- Klient: http://tyypvigaclient.azurewebsites.net/Memberarea , http://tyypvigaclient.azurewebsites.net/
- Server: http://tyypvigaserver.azurewebsites.net
- Dokk: http://tyypvigaserver.azurewebsites.net/Help (seisuga 29.05.2016 on sisestatud ainult sisulise osa päringute kommentaarid)
- Lähtekood: https://github.com/viilveer/vr2_asp (esialgu arendasin VSO'sse, kuna peab avalik olema siis tõstsin github'i ümber)
- Konto kõikide õigustega: U: administrator@tyyp.ee P: admin1
Projekti eesmärk oli luua kasutajatele keskkond, kus kasutaja saaks jagada enda sõidukitega toimuvat infot. Hetkel on olemas palju erinevaid automargi foorumeid, kus on sarnaseid teemasid väga palju. Kes tuunivad, kes ehitavad, kellel hobiauto, kellel niisama hea päevikut pidada. Kogu rakendus tiirleb ümber auto ning auto külge seotud blogidega. Kasutajad saavad blogisid märkida lemmikuks ning nendele tekib avalehele feed lemmik blogidest. Samuti kuvatakse avalehel uuemad blogid. Olemas on ka otsingu funktsionaalsus. Lisaks eelnevale on olemas ka sõnumivahetus osa. Kasutaja saab kirjutada teisele kasutajale, et küsida abi/nõu mingi mure kohta või siis niisama vestluseks.
Projekt valmis 99% Mihkli panusel seepärast on Mihkel teinud palju ohverdusi selleks, et projekt üldse mingil kujul oleks presenteeritav. Kuna Mihklil oli ka "ASP.NET veebirakendused" aine võetud, siis kliendipool sai tehtud spetsiaalselt selleks, et saada ka teine aine tehtud. Tänu sellele pühendas Mihkel ka sellele projektile rohkem aega. Kuna eesmärk oli saada projektile pilt ette ei kasutanud Mihkel igas kohas nn "best practise" nõuandeid. Näiteks sai ainukesena VehicleController endale Service'i ning suhtlemiseks kasutatakse DTO'si.
Idee
Projekti võtmesõnad:
tüüpvead, autod, mootorrattad, mootorpaadid, skuutrid, jetid jms. ülevaated, arvustused personalne <auto>blogi(build blog)
"Pitch"
Kasutajate sisendil baseeruv informatiivne keskond, erinevate mootorsõidukite, mootorsõidukite tüüpvigade, ülevaadete ja nende mootorsõidukitega kaasnevate tegevuste blogi/infosüsteem. Infosüsteem võimaldab kasutajate endi kogemust jagades aidata teisi kasutajaid ja veebisaidi külastajaid olulise infoga enne mootorsõiduki <ostu> ( näiteks tüüpvigadega varasemalt tutvudes. lugedes juba objekti omavate kasutajate kogemuse kohta ). Sellise info omamine aitab kasutajal teha targemaid otsuseid mootorsõiduki ostul, müügil, vahetamisel, tuunimisel, parandamisel, renoveerimisel, rekonstrueerimisel.
Kasutusele võetavad tehnoloogiad
Analüüs/Task breakdown
Task breakdown* v0.2
0. EPIC0 Mootorsõiduk kui MAIN ENTITY.
0.1 Mootorsõidukite Ülevaated, arvustused jms.
0.2 Mootorsõidukite ülevaateid ning arvustusi saavad kasutajd mugavalt otsida otsisõnade järgi.
0.3...
1. EPIC1 kasutaja kui MAIN ENTITY + rollid
1.1 Lugeda teiste kasutajate postitusi. Luua, muuta, kustutada isiklikke blogi postitusi, luua hashtage( hashtag claiming).
1.2 Jälgida( follow ) teiste kasutajate blogi postitusi. MAIN SALE
1.3 <niceToHave> Saata privaatsõnumeid kasutajate vahel.
2. EPIC2 otsingumootor
2.1 Võimaldab otsida võtmesõnu postituse pealkirjast ja postituse sisust.
2.2 Võimaldab kasutajal otsida teisi kasutajaid kasutajanime järgi.
2.3 <niceToHave> Võimaldab otsida #Hashtagide kaupa postitusi, kasutadeds '#' wildcardi ( #<otsitavHashtag> ).
3. EPIC3 blogi
3.1 Blogi postituse loomine.
3.1.1 Blogi postitus sisaldab: Valikut mis mõõtorsõiduki tüübile postitus luuakse, mudeli täpsustust ja mootorsõiduki väljalaske aastat. Postitusel on Pealkiri, mis ei ole kohustuslik. Sisu (WYSIWYG editor) väli. Piltide upload input. Hashtagide input.
- Pealkirja + #hashtag field mis aitab postitust hashtagi võtmesõnade abil unikaalsemaks muuta (hashtag claiming)
n: #AudiA6BumperReWork #päev1 jms.
- Pilte
- Hashtage( ? )
- Standard teksti formattimine. bold, italic, h1, h2, h3 <sellejaoks on raudselt mingi API olemas juba>
3.1.2 blogidele kommentaaride lisamine. nice to have.
4. EPIC4 hashtag cloud
4.1
5. EPIC5 front page www.<tyypviga>.<ee>
5.1 pikk otsingu lahter lehe ülal servas keskel.
5.2 ülal paremas nurgas kasutajaga seonduv.
5.3 viimati lisatud blogipostitused
5.4 populaarseimad blogi postitused ?( klickidel baseeruv )?
5.6 hashtag cloud enim kasutatud hashtagidega. ( #AudiA6 #BMW626 #Mootorratturid #CustomBuild jms. )
5.6.1 hastagcloudis hastagile klickides, suunab hastagi landing pageile, mis sisaldab <=10 postitust. Postitusi on võimalik juurde laadida kümne kaupa.
6. EPIC6 kasutajate vaade
6.1 Admin vaade - kasutajate ja kasutajate sisenedi administreerimise võimalused.
6.1.2 ebasobiva sisu kustutamine/modereerimine.
6.1.3 tavakasutajate modereerimine.
6.2 <niceToHave> Tavakasutaja vaade - info voog ja statistika tema personaalsete blogide/kommentaaride/kasutaja endi poolt loodud
- hastagide kasutatavuse ?( innustaks kasutajaid looma oma unikaalseid #hashtage )? kohta.
8. EPIC7 mitmekeelsus saidil (tõlked).
Omavahel sõltuvuses olevad EPICUD:
MAIN ENTITIES->
EPIC1->EPIC6->
EPIC3->EPIC2->EPIC5->
EPIC4->EPIC5->
EPIC7->
* "Leotav tekst ei ole kunagi lõplik, piisavalt rafineeritud ega korrektne- perfektset asja ei ole olemas." - <EndaArustTarkTüüp>
QSEE andmebaasiskeem
XML osa
XML Fail
<?xml version="1.0" encoding="UTF-8"?> <companies> <company id="1"> <name>Schmidt PLC</name> <workerCount>9</workerCount> <type>Information</type> <address> <street>8181 Volkman Place</street> <city>West Dewayne</city> <postcode>30030-1343</postcode> <country>Jersey</country> <phone></phone> </address> <employees> <employee contract="full-time" occupation="Compacting Machine Operator"> <name>Rogers Kutch Sr.</name> <phone>802-112-0733</phone> <salary>1152</salary> </employee> <employee contract="full-time" occupation="Electrical Engineer"> <name>Chelsea Turcotte DDS</name> <phone>818.181.9337x490</phone> <salary>3412</salary> </employee> <employee contract="full-time" occupation="Producer"> <name>Rey Altenwerth PhD</name> <phone>855.153.8231x79547</phone> <salary>3672</salary> </employee> <employee contract="full-time" occupation="Animal Control Worker"> <name>Maryse Schmidt</name> <phone>09527107290</phone> <salary>3539</salary> </employee> <employee contract="part-time" occupation="Educational Counselor OR Vocationall Counselor"> <name>Josie Baumbach</name> <phone>07180334208</phone> <salary>3019</salary> </employee> <employee contract="part-time" occupation="Fashion Model"> <name>Kareem Graham</name> <phone>425.306.3170</phone> <salary>3811</salary> </employee> <employee contract="part-time" occupation="Webmaster"> <name>Michaela Weissnat</name> <phone>1-688-533-3918x2902</phone> <salary>1124</salary> </employee> <employee contract="full-time" occupation="Nonfarm Animal Caretaker"> <name>Dr. Toney Hamill</name> <phone>1-626-583-8931</phone> <salary>2888</salary> </employee> <employee contract="full-time" occupation="Singer"> <name>Soledad Hansen</name> <phone>031.695.7461x523</phone> <salary>2087</salary> </employee> </employees> </company> <company id="2"> <name>Langworth, Conroy and Bauch</name> <workerCount>7</workerCount> <type>Arts, Entertainment, and Recreation</type> <address> <street>615 Gorczany Rapids</street> <city>West Hyman</city> <postcode>72688</postcode> <country>Angola</country> <phone>04554658252</phone> </address> <employees> <employee contract="full-time" occupation="Computer Security Specialist"> <name>Tyrese Auer</name> <phone>(238)773-9387x4752</phone> <salary>1063</salary> </employee> <employee contract="full-time" occupation="Railroad Yard Worker"> <name>Ms. Danielle Russel Jr.</name> <phone>+73(2)2183429933</phone> <salary>3038</salary> </employee> <employee contract="full-time" occupation="Steel Worker"> <name>Mrs. Elza Koch I</name> <phone>(384)024-0108</phone> <salary>2709</salary> </employee> <employee contract="part-time" occupation="Petroleum Pump System Operator"> <name>Jermaine Hegmann</name> <phone>427.168.3059x031</phone> <salary>2729</salary> </employee> <employee contract="full-time" occupation="Human Resources Assistant"> <name>Ms. Sydni Marquardt</name> <phone>701.387.7215x03428</phone> <salary>1747</salary> </employee> <employee contract="full-time" occupation="Optometrist"> <name>Miss Rosella Swift DDS</name> <phone>737-209-4634x8495</phone> <salary>2708</salary> </employee> <employee contract="full-time" occupation="Correspondence Clerk"> <name>Letitia Buckridge</name> <phone>526-083-7143x036</phone> <salary>3587</salary> </employee> </employees> </company> <company id="3"> <name>Altenwerth, Zemlak and Mraz</name> <workerCount>6</workerCount> <type>Information</type> <address> <street>16060 Crystal Grove</street> <city>Rippinton</city> <postcode>16164-5194</postcode> <country>Swaziland</country> <phone>(966)924-6974</phone> </address> <employees> <employee contract="part-time" occupation="Milling Machine Operator"> <name>Robb Gulgowski</name> <phone>08557661700</phone> <salary>3030</salary> </employee> <employee contract="part-time" occupation="Cartographer"> <name>Dr. Adaline Reinger</name> <phone>1-004-556-1080x74960</phone> <salary>3876</salary> </employee> <employee contract="full-time" occupation="Carpenter Assembler and Repairer"> <name>Velda Sanford</name> <phone>431.198.4270</phone> <salary>2913</salary> </employee> <employee contract="full-time" occupation="Government"> <name>Garret Armstrong</name> <phone>702-909-3199</phone> <salary>1597</salary> </employee> <employee contract="part-time" occupation="Telephone Station Installer and Repairer"> <name>Claire Predovic</name> <phone>007.971.7079x723</phone> <salary>2871</salary> </employee> <employee contract="full-time" occupation="Meter Mechanic"> <name>Loyce Ebert</name> <phone>651-879-5115x1261</phone> <salary>2058</salary> </employee> </employees> </company> </companies>
XSLT
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" > <xsl:output method="html" indent="yes"/> <xsl:key name="companiesByType" match="type" use = "current()"/> <xsl:template match="/"> <html> <body> Ettevõtted grupeeritud tegevusala järgi: <ul> <xsl:for-each select="/companies/company/type[generate-id(.) = generate-id(key('companiesByType', .)[1])]"> <li> <h1> <xsl:value-of select="."/> </h1> <xsl:variable name="typeVal" select='.' /> <ul> <xsl:for-each select="//companies/company[type = $typeVal]"> <li> <h2> <xsl:value-of select="name"/> </h2> <p>Aadress: <xsl:value-of select="address/street"/>, <xsl:value-of select="address/postcode"/>, <xsl:value-of select="address/country"/></p> <p>Telefon: <xsl:choose> <xsl:when test="not(address/phone)"> <xsl:text>Salastatud</xsl:text> </xsl:when> <xsl:when test="address/phone = ''"> <xsl:text>Ei ole sisestatud</xsl:text> </xsl:when> <xsl:otherwise> <xsl:value-of select="address/phone"/> </xsl:otherwise> </xsl:choose> </p> <h3>Töötajad</h3> <ul> <xsl:for-each select="employees/employee"> <li> <xsl:value-of select="name"/> (Telefon: <xsl:value-of select="phone"/>, tööleping: <xsl:value-of select="@contract"/>) </li> </xsl:for-each> </ul> </li> </xsl:for-each> </ul> </li> </xsl:for-each> </ul> </body> </html> </xsl:template> </xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" > <xsl:output method="html" indent="yes"/> <xsl:template match="/"> <html> <body> Töötajate palgad: <ul> <xsl:for-each select="//companies/company"> <li> <xsl:value-of select="name"/> <xsl:variable name="avgSalary" select="round(sum(employees/employee/salary) div count(employees/employee))"/> (Keskmine töötasu: <xsl:value-of select="$avgSalary"></xsl:value-of>) <ul> <xsl:for-each select="employees/employee"> <li> <xsl:variable name="employeeSalary" select="salary"></xsl:variable> <xsl:variable name="comparedToCompanyAvg" select="$avgSalary - $employeeSalary"></xsl:variable> <xsl:value-of select="name"/> (Töötasu kuus: <xsl:value-of select="salary"/>, teenib keskmisest: <xsl:value-of select="translate($comparedToCompanyAvg, '-', '')"/> <xsl:choose> <xsl:when test="$comparedToCompanyAvg > 0"> vähem </xsl:when> <xsl:otherwise> rohkem </xsl:otherwise> </xsl:choose> ) </li> </xsl:for-each> </ul> </li> </xsl:for-each> </ul> </body> </html> </xsl:template> </xsl:stylesheet>
XSD Fail
<?xml version="1.0" encoding="utf-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="companies"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="company" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="workerCount" type="xs:unsignedInt" minOccurs="1" maxOccurs="1" /> <xs:element name="type" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="address" minOccurs="1" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element name="street" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="city" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="postcode" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="country" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element minOccurs="0" name="phone" type="xs:string" maxOccurs="1"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="employees"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="employee" minOccurs="1"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="phone" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="salary" type="xs:unsignedInt" minOccurs="1" maxOccurs="1"/> </xs:sequence> <xs:attribute name="contract" type="xs:string" use="required" /> <xs:attribute name="occupation" type="xs:string" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="id" type="xs:unsignedInt" use="required" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
XML retsensioonid
Retsensioon 1
Meeskond Aeg on kirjutanud XMLi, mis kajastab kasutaja tehtud tööd etteantud nädalal päevade kaupa. XML on vastab ülesannete nõuetele, sisaldades viite dimensiooni ning kolmel elemendil on lisatud atribuut, mis ei ole ID. XSD loomisesse ei ole aga väga palju vaeva pandud. Tegemist on Visual Studio genereeritud failiga, milles on andmetüübid muutmata jäänud. Näiteks on atribuut ID tüübiks jäetud unsignedByte, mille tõttu saab süsteemis olla kuni 255 ajaraportit. Samuti oleks võinud lahendada elemendi time atribuudi unit väärtused enumitega. Ajaühikud on ikkagi fikseeritud. Time element ise peaks olema ka fikseeritud kindlasti maksimum väärtusele 24, kuna ühes päevas rohkem aega ei ole. Ning samuti ei tohiks olla lubatud 0. XSLT'd on üsna lihtsakoelised ning esimene ei vasta ülesande nõudele, kuna on puudu tingimuste kontroll. Samuti pole kummagis transformatsiooni failis kasutatud muutujaid. HTMLi transformeerudes joonistatakse valmis tabel, mille ühel real on ülesanne, kuupäev ning selleks kulunud aeg. Leiame, et XMLi log element võiks sisaldada endas rohkem parameetreid. Näiteks võiks olla iga sisestuse kohta kommentaari väli, kuhu saab kirjutada, mida selle ajaga tehti (alati ei saa kohe taski valmis, tööandajale väga oluline väli). Võiks olla ka optional väli, kuhu saaks toppida taski lingi, siis saaks ajahinnangu rakendusest otse klikiga liikuda keskkonda, kus on taskid. Aga idee on hea ning esialgseks prototüübiks sobib see XML hästi.
Retsensioon 2
Meeskond Travo_2.0 on loonud XML/XSD/XSLT. XML hoiab koolis käivate õpilaste andmeid.
XML vastab laiaslaastus ülesannete nõuetele, sisaldades viite dimensiooni kuid ei ole väga kasutatud atribuute va. ID. Tegemist on koolis oleva klassi süsteemi kirjeldava XML'iga. Isikliku eelistusena oleksin <Groups> asendanud <Classes> ja <Group> <Class>'iga (kuna XML alguses olev kommentaar vihjab Klassidele mitte gruppidele mis kaotab kommentaari lisamise mõtte. Kommentaarid peaksid abistama sisu mõistmisel.) Lisa atribuutide soovitusena oleks võimalik olnud kasutada groupId="" atribuuti <Student> elemendis mis olekes elemedi sisu jätnud ainult tudengi/õpilase isiklike andmeid sisaldavate elementide jaoks (<Contacts>, <EnrolledCourses> jne.). XSD on VS poolt genereeritud ja atribuut ID tüübiks jäetud unsignedByte mis ei võimalda rohkemat kui 255 väärtust. Kuna andmeid on väga vähe XMLis, siis on raske mingeid reegleid XSD'sse panna. On näha, et autor on vähemalt ära määranud miinimum ja maksimum pikkused õppejõu nimele. XSLT ülesanne on jäänud poolikuks, kahest on tehtud üks. XSLT keelesüntaksit oleks võinud rohkem kasutada (puudu on tingimuste kasutus ja soovituslik muutuja kasutamine), HTMLi on samas piisavalt kirjutatud.
Server/kliendirakenduse retsesnsioon Skeddl'e
- Üldpilt: Kogu rakendus on jaotatud ilusti loogilisteks projektideks. Ei saa hästi aru mida teeb ClientRepo projekt solutionis. Aluseks võetud ilmselt Web & WebAPI projekt. Klasside nimetusel on osad klassid mingil põhjusel snake_case'is, tegemist pole otseselt veaga vaid stiiliprobleemiga. Alles on jäetud ka klassid mida pole vaja. Äriloogika tükke eraldi ei leia, kogu loogika laotud controlleritesse. samuti puudu service'd.
- Serverrakendus : Klientrakendus kasutab serveriga suhtlemiseks serverrakendust. Serverrakenduse jaoks on eraldi olemas projekt DAL. Serverrakenduse aluseks on ilmselt võetud kliendipool kirjutatud kontrollerid ning siis kirjutatud API sisu asemele. Sellisel lähenemisel on omad kiiksud - võib tekkida olukordi, kus API teeb vähem, kui rakendus nõuab. Näiteks, kui süsteemis salvestatakse mingi kanne, mis eeldab ka mingit muud toimingut, kuid see toiming tehakse muu API päringuga. Samuti annab see märku, kuidas on andmebaas struktureeritud. Ilusti on kasutatud "Route" annotatsioone, kuid REST teenust see väga ei meenuta (sama häda ka enda projektis, kuid osades kohtades katsusin RESTi jälgida). Näiteks Subjectcontroller::GetSubjectById() võiks olla mapitud "api/Subject/{id}" vastu. Hetkel on urlis sees veel SubjectGetById, mis on sisuliselt irrelevantne. Järgnev mis silma hakkas on ka enda projektis probleemiks, kui manipuleeritakse mingit resurssi, mis on mingi resursi osa - näiteks kasutaja subjektid, siis võiks meenutada url midagi sellist: "user/{userId}/subjects".
REST best practices: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
- Klientrakendus: Mõned actionid on muutunud üsna lohisevaks ning võiks olla eraldi klassis, mis tegeleb mingi tegevusega (TasksController::Index). On kasutatud annotatsioone(mis meetodile vastab mingi action, custom route'd). Tundub, et on olemas ka turvavead. Mitmetes actionites tehakse päringuid ainult findById() meetodit kasutades. Väga paljud controllerid on ilma authorize annotatsioonita, mis tähendab, et voli igale poole ligi saada on olemas. Oleks olnud hea ka praktiseerida role based accessi, ehk siis omistada kasutajatele rollid ning kasutada neid rolle Authorize meetodis. Hea näide turvaprobleemist on näiteks SubjectsController::Unsubscribe, õiguseid pole piiratud aga samas otsib controller User.Identity alt aktiivset kasutajat. Siinkohal siis tekib kohe nullpointer. CommentsController::deleteConfirmed on imelik, kuna leitakse mingi TaskId aga samas ei kontrollita selle põhjalt mitte midagi. On olemas ka eraldi DAL projekt, kuid halb on see, et kasutatakse samu interface'i mida kasutatakse serveri DAL osale. Enda projektis tekkis ka sama häda. Häda on selles, et meetodid on interface'is defineeritud domeenimudelitga aga need hakkavad reetma andmebaasi struktuuri. Sestap peaks kasutama erinevates DAL projektides erinevaid interface'i. Siis saaks kasutada ka DTO'sid andmete postitamisel kui ka lugemisel. Minu arvamus API'dest on see, et tagastada võiks enamat, kui lihtsalt bool'i või tühja returni. Eriti halb olukord tekib näiteks UserSubjectRepository::SubscribeUser'i meetodis kus return on sama, kuigi kontroll on staatus koodi jaoks olemas.
- Kokkuvõte: Arvan, et autorid on teinud hea töö ning mõistavad, kuidas koostada API teenust.