Om du arbetar med webbtjänster

Den här artikeln är en undersökning av webbtjänstprotokoll, vanliga datautbytesformat och bästa praxis. Om du är intresserad av att skapa prestanda mobila applikationer som ansluts till webben, läs vidare!


Välja ett protokoll och dataformat

Att välja ett korrekt protokoll och datautbytesformat för att skicka data mellan din mobilapp och nätet är ett av de viktigaste besluten att göra under utvecklingsprocessen. De vanligaste och mest använda protokollen är REST, XML-RPC och SOAP.

Alla dessa protokoll transporterar data över HTTP-protokollet. XML-RPC- och SOAP-protokollen är XML-baserade, medan REST-tjänster kan förlita sig på olika dataformat, de två vanligaste egenskaperna XML och JSON. SOAP i synnerhet uppskattas och antas av företagsapplikationer, eftersom det strikt tillämpar datamodeller och beskriver offentliga gränssnitt genom WSDL, vilket gör att vissa utvecklingsverktyg (t.ex. Microsoft Visual Studio för .NET) kan automatiskt ställa in föremål och metoder att konsumera tjänsterna bara genom att lägga till en referens till tjänsten WSDL till projektet.

XML är emellertid genom design mindre effektiv än JSON när den används i ett begränsat nätverksscenario med bandbredd som mobil utveckling. Mobila datanätverk (WWAN) är vanligtvis mindre tillförlitliga än trådbundna (LAN) eller trådlösa (WLAN) nät, eftersom klienter på resande fot kan enkelt släppa in och ut ur täckningsområden. Dessutom abonnerar vissa användare inte på "platt" dataplaner och debiteras faktiskt av nätverkstrafik.

Så samtidigt som du utvecklar för mobil bör du alltid välja enkelhet och trafikminskning.

Låt oss jämföra vanlig XML till JSON med ett exempel svar:

XML

  Hej, enhet! 

JSON

 returnValue: "Hej, enhet!" 

Som du kan se, JSON har en mindre nyttolast eftersom det bara behöver vikla data med parentes (lockigt för objekt, kvadrat för arrays) och citat, medan XML behöver en fullständig rotnod och öppnings-stängningskoder för varje element eller grupp. Att spara på de här taggarna kan avsevärt trimma ner nyttolastningen och ju mer data du överför, desto större blir nyttolastningen "padding" med XML.

Dessutom kräver SOAP och XML-RPC mer komplexa XML-datastrukturer (som SOAP-kuvertet), vilket ger extra vikt till nyttolasten.

Av denna anledning rekommenderar jag att du väljer JSON för appens datautbytesformat och RESTEN för överföringsprotokollet, om inte XML, SOAP eller XML-RPC uttryckligen krävs för dina behov. Skulle du behöva upprätta en datamodell, kan du uppnå det med JSON också med hjälp av JSON Schema eller WSDL 2.0.

För referenser och ytterligare läsning om de diskuterade protokoll och dataformat, kolla in följande:

  • JSON vs XML Debate
  • JSON Översikt
  • XML-översikt
  • XML-RPC-översikt
  • SOAP Översikt
  • JSON-hemsidan
  • Mer om WSDL

Nätverkssäkerhetsöverväganden

Eftersom de flesta webbtjänster fungerar via offentliga nätverk, är skyddet av data som ska utbytas mellan tjänsterna och appen en av de mest kritiska frågorna som du behöver adressera. Många webbtjänster tillhandahåller fjärrfunktionalitet till autentiserade användare, så även privata användardata och autentiseringsuppgifter måste överföras över nätverket..

Personuppgifter, kontodata och referenser ska aldrig resa i klartextform över ett offentligt nätverk, så det betyder att dina webbtjänster och appar ska implementera kryptering. Den goda nyheten är att de vanligaste protokollen transporterar data via HTTP, så att du kan lita på välkänt, pålitligt och robust HTTP SSL / TLS-protokoll (HTTPS) som har utbrett stöd både på serversidan och på klientsidan.

Att aktivera SSL på vanliga webbservrar är ganska lätt (det finns många användbara resurser för Apache, IIS och Nginx). Allt du behöver göra är att köpa ett SSL-certifikat och ställa in det på din server. I en i värsta fall, Du kan också utfärda ett självtecknat certifikat som ger dig gratis kryptering, men jag skulle inte rekommenderar att du gör det. Vissa certifikat utfärdar billiga certifikat, och fördelarna med att arbeta med ett betrodat, signerat certifikat är värda extrakostnaden (det vill säga att förhindra man-i-mitten attacker genom att använda PKI). Användning av självtecknade certifikat kan också kräva extra kodning eller till och med applikationsspecifika "hack", eftersom vissa nätverksbibliotek kommer att vägra otillförlitliga HTTPS-anslutningar (kolla dessa artiklar om Android, # 1 och # 2 och om iOS).

Att aktivera SSL på klientsidan är en no-brainer: vanliga programmeringsspråk har vanligtvis HTTP-klasser och bibliotek som tillhandahåller inbyggt HTTP-SSL-stöd och kommer "automagiskt" att ta hand om kryptering bara genom att använda "https: //" webbadresser i stället för "http : // "webbadresser för att konsumera webbtjänster.

Om du väljer ett lågprissatt SSL-certifikat, kontrollerar du bara att de enheter och operativsystem du vill utveckla för har utgivarens CA-rootcertifikat buntat inuti rutan, annars kommer de inte att lita på certifikatet.

Du bör aldrig be användarna att lappa, ändra eller hacka sina system för att kunna köra dina appar, och om du gör det, förvänta dig inte att många av dem följer.

Web Service Authentication

Autentisering för REST-baserade tjänster

Tokenbaserad autentisering

Web Services transaktioner är menade att vara atom-, kompatibla och skalbar, så webbtjänster är vanligtvis statslös (kolla in denna intressanta diskussion om betydelsen av "statslös" anslutningar).

Många webbtjänster ger användarrelaterad funktionalitet och tillgång till känslig information. Naturligtvis krävs det autentisering. Eftersom sådana transaktioner är statslösa behövde du traditionellt att skriva in förfrågningar med en användarspecifik nyckel, vilket ger autentisering med varje fjärranslutet metodsamtal. Även vid överföring av data över HTTPS är användaruppgifterna högst riskfyllda när de överförs via ett offentligt nätverk. Kryptering bryts ibland.

Detta dilemma är där tokenbaserad autentisering som OAuth kommer till nytta. Med hjälp av tokenbaserad autentisering behöver du bara skicka en användares referenser en gång. Om användaren är autentiserad, kommer de att vara försedda med tokens som kan användas för att verifiera efterföljande fjärranslutna metallsamtal.

En tokens giltighet sträcker sig över en begränsad livstid och kan återkallas när som helst av dess emittent (det vill säga serverns sida). Med tokenbaserad autentisering kan du också dela samma användaruppgifter mellan olika appar och tjänster utan att de länkade tjänsterna / appen någonsin känner till de riktiga användaruppgifterna. Vidare håller denna autentiseringsmetod säkert en lokal cache av referensuppgifterna på användarens enhet, så att användaren kan "komma ihåg" och inte behöver verifiera varje gång han kommer att använda appen (skriva komplexa lösenord på handdatorer kan vara en riktig smärta och kan dåligt skada app recensioner).

OAuth-baserad autentisering

OAuth är den vanligaste tokenbaserade authramen och den har antagits av stora spelare som Google, Twitter, Facebook, och så vidare. Genom att tillåta användare att återanvända sina befintliga konton, hoppa över irriterande registreringsblanketter och hålla kontroll över tillgången till personuppgifter kan du öka användarnas användningsnivå avsevärt.

Vissa OAuth-leverantörer kräver att deras egna SDK importeras i dina appar för att aktivera autentisering, annars finns det många färdiga OAuth-bibliotek runtom det du kan ansluta till din app. Det finns också ramar som oauth-php tillgängliga för att bygga egna OAuth-leverantörer.

Jag skulle föreslå skylt som ett Android OAuth-klientbibliotek och oauthconsumer för iOS.

Alla dessa bibliotek kommer med användbara exempel och är lätta att genomföra. Att bygga signpostkällor på din maskin eller importera dem till din app kan dock vara lite ont, men du behöver inte faktiskt gå igenom den processen. I stället kan du bara importera JAR-binärerna till ditt projekt och du bör ställa in. På IOS skulle det här likna att importera ett statiskt bibliotek (* .a-fil) till ditt projekt.

Autentisering för SOAP-baserade tjänster

Den vanligaste autentiseringsmetoden för SOAP-baserade tjänster är en SOAP-förlängning som kallas HTTP Basic Authentication (kallas ibland Digest Authentication). Detta är ett standard, välunderbyggt förfarande som är integrerat i alla de vanligaste webbservrarna, som Apache, Nginx och IIS. Den är baserad på ett användarnamn-lösenordspar som måste skickas till servern via HTTP-rubriker.

Normalt behöver du inte manuellt genomföra grundläggande auth i dina applikationer, eftersom den också är brett stödd på de vanligaste programmeringsspråken. .NET Framework bygger på NetworkCredential-klassen för att tillhandahålla grundläggande och smälta auth-referenser till HTTP-förfrågningar, PHP stöder det via cURL och Java via Authenticator.

Skulle du behöva implementera Basic Auth själv behöver du bara lägga till den här rubriken på dina önskemål:

 Grundläggande användarnamn: lösenord

Värdena "användarnamn" och "lösenord" måste vara base64-kodade.

Vänligen notera det HTTP Basic Auth används bäst i kombination med HTTPS-protokollet, eftersom det överför behörighetsuppgifter i oformatterad text form. Digest Auth är lite säkrare, eftersom det faktiskt hakar lösenordsvärdet, men HTTPS rekommenderas ändå för att undvika hash bruteforce attacker.

Mer detaljer och specifikationer om detta ämne finns i IETF RFC 2617 memo.

Native Platform Authentication Libraries

När du väljer en autentiseringsmetod eller integrerar kända tjänster (t.ex. sociala nätverk), bör du också beakta de inbyggda bibliotek som är inbyggda i många avancerade plattformar som iOS och Android. Detta kan spara mycket tid och många rader av kod.

Android ger en bra ram för att centralisera användarkontot hantering, klassen AccountManager. Den officiella Android Developer-guiden ger en del bra dokumentation för den här klassen, tillsammans med några tips för att integrera OAuth 2 eller skriva din egen "Anpassad kontotyp".

Med iOS 6 har Apple introducerat en ny social ram för att integrera stora tjänster som Twitter, Facebook och Sina Weibo på OS-nivå. Även om du inte behöver integrera dessa tjänster i din ansökan, kan du hitta ett lämpligt sätt att dra nytta av de inbyggda autentiseringsmetoderna via anpassning.


Optimeringstips

Datakomprimering

När du utvecklar för mobila applikationer är det viktigt att hålla dina data nyttolaster så låga som möjligt. Detta avsnitt kommer att diskutera flera strategier för att göra det.

Arkiveringsdata

ZIP-komprimering kan avsevärt minska text och binär datavikt och stödjas väl på de flesta plattformar, så använd det bra om du behöver överföra stor data via mobilnät. Användbara bibliotek för att hantera ZIP-filer är tillgängliga för Android (dvs dekomprimera) och iOS (dvs Ziparchive).

Effektiv Media Streaming

Om du behöver strömma ljud / videoinnehåll till dina mobilappar väljer du avancerade strömmande plattformar som tillåter dem att skala flöden beroende på nätverks / enhetens prestanda, som Apples HTTP Live Streaming (HLS) -protokoll. Annars är det vanligtvis ett bra val att gynna responsen över mediekvaliteten. Spela runt med olika video- och ljudkompressorer och inställningar, optimera så mycket du kan. Du kan också gruppera enheter av olika slag (handdatorer med liten bildskärm, handdatorer med bred skärm och surfplattor) och leverera olika innehåll för varje sort.

Problemet med HD

Många mobila enheter har HD-skärmar, men är HD-innehåll på små skärmar verkligen värda extra bandbredd? Var uppriktig om relevansen av mediekvaliteten i dina appar och försök att hitta den bästa balansen mellan kvalitet och vikt.

Lokal caching

Låt oss anta att du ska koda en läsarapp för en online tidning. Först och främst bör du alltid låta dina användare fungera offline när det är möjligt. Medan vissa appar alltid kräver ett aktivt nätverk (dvs. meddelandetjänster), bör många andra bara använda nätverket till ladda ner datapaket och cache dem på enheten.

Detta kommer att förbättra programmets prestanda, spara användarens pengar på icke-platt mobila dataplaner och göra appen användbar när nätverket inte är tillgängligt (t.ex. under flygning).

När du hämtar innehåll på enheter som lagrar externt lagringsutrymme (t.ex. minneskort), ska du låta användarna välja varifrån lagras nedladdat innehåll (dvs. internt eller externt lagringsutrymme) eller hur som helst föredrar externt lagringsutrymme. Entry level-enheter har vanligtvis ganska liten intern lagring och kan bli instabila eller långsamma när internt lager är fullt. Om dina appar tar upp mycket lagringsutrymme, kommer de troligtvis att avinstalleras för att spara utrymme.

Chunking Data

Låt oss gå tillbaka till läsapplikationsexemplet. Varje artikel är en enda del, och även om artiklar kan länkas samman, finns det ingen anledning till varför du inte bör låta användare börja läsa artiklar även om ytterligare innehåll fortfarande laddas ner. Så, packa varje artikels filer (text, bilder, bilagor och media) i separata ZIP-arkiv och tillhandahålla en webbtjänst metod för app att hämta lista över tillgängliga artiklar. Få din app att ladda ner ZIP-paket en och en och gör dem tillgängliga i appen så snart som alla har laddats ner och medan andra laddas ner i bakgrunden. Det här är en bra prestanda och förbättrad användarupplevelse jämfört med att du väntar tills hela nyttolasten har laddat ner! Du kan också låta användare välja vilka paket de vill ladda ner eller inte (så att de kan spara utrymme, tid och trafik) och låta dem ta bort enskilda paket för att spara lagringsutrymme utan att ta bort hela appen.

Följande är ett svar från demo-serverns app som bifogas denna artikel:

 apiversion: 1, status: 0, paket: [fil: "pack01_01_01.zip", paket: "pack01", appversion: 1, revision: 1, fil: "pack01_02_01.zip", paket: "pack01" , appversion: 2, revision: 1, fil: "pack02_01_01.zip", paket: "pack02", appversion: 1, revision: 1]

Ändra hantering

Tänk på att din app och tidigare släppt innehåll kan utvecklas över tiden.

Ge en "revision" -flagg för varje paket i listmetoden. Det här kommer att vara till nytta för att släppa uppdateringar, fixa fel i innehållet och implementera autoupdate-funktionalitet i dina appar. Även om du inte planerar att genomföra automatisk uppdatering, tänk dig framåt och sätt ändringsflaggan i din lista ändå för framtida utveckling.

Du bör också inkludera en "app-version" -flagga i din paketlista. Skulle du utfärda en ny större version av din app som innebär bristande ändringar i innehållsformat, så låter du ge innehåll för både nyare och äldre appar via samma webbtjänst.


Feltolerans och Fjärradataåterställning

Medan du utvecklar servicebaserade appar, nätverk och enhet feltolerans bör också beaktas. Mobila dataanslutningar är vanligtvis mindre stabila än kabeldragna, apps kan avinstalleras och installeras om igen och enheter kan gå vilse, ersättas med nyare eller återställas på fabriken. Användare bör ges möjlighet att återställa appar och innehåll på ett enkelt sätt, och plattformsutvecklare erbjuder flera användbara färdiga lösningar på dessa problem.

Övervakning av nätverksstatus

Kom ihåg att Kontrollera alltid nätverksstatus innan du ringer fjärrtjänster eller hanterar noggrant I / O-fel i nätverket och informerar dina användare korrekt om den önskade uppgiften inte kan uppnås på grund av bristen på en aktiv datakoppling. Om dina appar alltid behöver "fungera online" kanske du vill lägga en vakthund i dina appar som ständigt övervakar nätverksstatus och brinner en händelse när en förändring uppstår. Du kanske också vill informera användare om eventuella extrakostnader när du överför stora mängder data via 3G eller roamingnät i stället för Wi-Fi.

På Android-enheter kan den här uppgiften åstadkommas via ConnectivityManager, och genom SCNetworkReachability på IOS (kontrollera även den bifogade provappen).

Återställ innehåll och inställningar

Både Android och iOS ger användbara API-skivor för att hantera fjärransluten cloud-säkerhetskopiering av användarappdata som du bör tänka på. Kontrollera dokumentationen för iCloud API för iOS och dokumentationen för Android Backup Service för Android. Tillsammans med inbyggda säkerhetskopieringstjänster får du också bra datasäkerhetsfunktioner. Du måste dock vara försiktig så att du inte överbelastar säkerhetskopieringstjänster med överflödiga eller onödiga säkerhetskopior.

Du kan också implementera anpassad fjärrdatasäkerhet i dina webbtjänster, men jag rekommenderar dig starkt att hålla dig till standard och inbyggda plattforms-API. De sparar vanligtvis tid och de underhålls aktivt av programvaruutvecklare på plattformen. OS-patchar är också mer benägna att installeras omedelbart när de släpps.

Återställa köp i appar

Om du levererar betalat innehåll via fakturering i appen i din app tillåter användare att återhämta sina inköp efter app återinstallerar och enhet återhämtning är obligatorisk. Lyckligtvis har iOS och Android inbyggda API för att hantera dessa scenarier också.

När dina app-inköpsaktiverade appar körs för första gången (eller första gången efter en ominstallation), bör du köra en återställningskontroll för köp. Både iOS och Android ger fin officiell dokumentation om denna fråga.

När du utvecklar för Android, kom ihåg att endast "hanterade" objekt kan återställas vid en senare tidpunkt, och de är bara tillgängliga för ett engångs-köp. Detta innebär vissa överväganden som gäller även iOS-utveckling.

Låt oss anta att du ska utveckla ett rollspel och vill tillåta spelare att köpa saker som hälso potions genom fakturering i app. Först och främst, eftersom användare kan köpa så många potioner som de vill, kan de inte "hanteras" saker, så deras köptransaktioner lagras inte permanent. Om en användare köper 20 drycker och använder 10, avinstallerar och återställer spelet senare. Om du återställer inköp via ett enkelt standardprocedur placeras 20 drycker tillbaka i användarens inventering, varav 10 är en oavsiktlig fri gåva från utvecklarna.

Så du kan behöva implementera egna anpassade webbtjänster och appmetoder för att hantera transaktionslagring och återställning i komplexa scenarier eller kantfall.


Designing for the Future

Tidsfrister och budgetar kommer ofta att skära av dig och inte låta dig följa alla de bästa metoderna som beskrivs i den här artikeln. Men även om du tvingas hålla fast vid en mindre delmängd av funktioner, tänka framåt, spendera lite tid i bra design, och packa dina metoder och klasser i bibliotek att du kan återanvända och förlänga senare. Lämna stubbar när du känner att det finns utrymme för vidare utveckling. Försök också att genomdriva bakåtkompatibilitet när du utökar och förbättrar dina bibliotek, så att äldre applikationer kan patchas också.

Detta är ett exempel på en stubben:

 public void sendData (Objektdata) om (validera (data)) client.send (data);  // Stub public boolean validate (Objektdata) // TODO - Implementera data validering return true; 

Slutsats: Var ska man gå här?

Om du är en nybörjareutvecklare eller aldrig har utvecklat servicebaserade applikationer, bör du börja från det bifogade provprogrammet som en bra övning för att förbättra din kunskap och göra den till en verklig applikation som tillämpar alla begrepp som förklaras i den här artikeln en i en tid. Alternativt kan du starta en ny applikation från början och integrera den med någon befintlig tjänsteleverantör (Facebook, Twitter, Last.fm eller Dropbox skulle vara en bra utgångspunkt) enligt samma schema.

Om du redan har utvecklat några tjänster och nätverksbaserade applikationer kan du granska din befintliga kod och förbättra dem enligt principerna ovan, hålla reda på varje förbättring och påverkan på prestanda och lyhördhet.

Glöm inte att kolla in de länkade resurserna, eftersom de kommer att ta dig djupare in i kärnan i varje problem och ladda ner provservern och klientapplikationer som medföljer artikeln.