Casa / Tutorial Windows / Cos'è il server API. Architettura client-server competente: come progettare e sviluppare correttamente un'API web. Spunti di riflessione

Cos'è il server API. Architettura client-server competente: come progettare e sviluppare correttamente un'API web. Spunti di riflessione

API Server accetta tutte le richieste API da applicazioni esterne. Per autenticare gli utenti, API Server utilizza un sistema di autenticazione simile alla crittografia a chiave pubblica.

Sistema crittografico a chiave pubblica (o crittografia asimmetrica, cifratura asimmetrica) - un sistema di crittografia e / o elettronico firma digitale(EDS), in cui chiave pubblica trasmesso su un canale aperto (cioè non protetto, accessibile per l'osservazione) e viene utilizzato per verificare la firma digitale e per crittografare il messaggio. Viene utilizzato per generare un EDS e decifrare un messaggio La chiave segreta.

Tutte le richieste al server API vengono effettuate al file del front controller. È in questo file che vengono identificate le chiavi pubbliche e private.

Qui descrizione passo passo questo processo:

  • Una richiesta dal client API arriva al server nella posizione del file del front controller. La richiesta contiene l'ID APP (la chiave pubblica del client) e l'APP KEY (una stringa di 32 caratteri crittografata con la chiave privata del client). La chiave segreta non viene mai inviata al server, viene utilizzata solo per crittografare la richiesta. La richiesta contiene i parametri della chiamata al server: utente, password di accesso, nome del controller e azione che dovrebbe elaborare la chiamata del client. Ad esempio, una serie di opzioni potrebbe essere simile a questa:
$items = array("controller" => "todo", "action" => "read", "username" => $username, "userpass" => $userpass);
  • Quando arriva una richiesta all'API Server, il server controlla l'elenco delle applicazioni per la presenza di una chiave pubblica (APP ID);
  • Se la chiave pubblica non viene trovata, un'eccezione del tipo "Request is non valido". Se la chiave è presente, il server prende la chiave segreta che corrisponde a questa chiave pubblica e tenta di decifrare la richiesta in arrivo;
  • Se la decrittografia ha avuto successo, i parametri del controller e dell'azione vengono estratti dalla richiesta in entrata ed elaborati. Il front controller che gestisce la richiesta si connette file desiderato controller e richiama l'azione contenuta nel parametro action;
  • In caso di successo/fallimento nell'elaborazione della richiesta, il client riceve una risposta dall'API Server.

Vladimir, lo sviluppatore web di Noveo dice

La maggior parte degli sviluppatori di siti Web, servizi Web e applicazioni mobili prima o poi deve fare i conti con un'architettura client-server, ovvero sviluppare un'API Web o integrarsi con essa. Per non inventare ogni volta qualcosa di nuovo, è importante sviluppare un approccio relativamente universale alla progettazione di API Web, basato sull'esperienza di sviluppo di sistemi simili. Portiamo alla vostra attenzione una serie combinata di articoli su questo tema.

Primo approccio: gli attori

Ad un certo punto, nel processo di creazione del prossimo servizio Web, ho deciso di raccogliere tutte le mie conoscenze e pensieri sull'argomento della progettazione di un'API Web per soddisfare le esigenze delle applicazioni client e organizzarle sotto forma di un articolo o di un serie di articoli. Naturalmente, la mia esperienza non pretende di essere assoluta, e le critiche costruttive e le aggiunte sono più che benvenute.

La lettura si è rivelata più filosofica che tecnica, ma per gli amanti della parte tecnica ci sarà qualcosa a cui pensare qui. Dubito che dirò qualcosa di fondamentalmente nuovo in questo articolo, qualcosa che non hai mai sentito, letto o pensato su te stesso. Sto solo cercando di adattare tutto unico sistema, prima di tutto nella tua testa, e questo vale già molto. Tuttavia, sarò felice se le mie invenzioni ti saranno utili nella tua pratica. Quindi andiamo.

Cliente e server

server in questo caso consideriamo una macchina astratta sulla rete in grado di ricevere una richiesta HTTP, elaborarla e restituire una risposta valida. Nel contesto di questo articolo, la sua essenza fisica e l'architettura interna sono del tutto irrilevanti, che si tratti di un laptop per studenti o di un enorme cluster di server industriali sparsi per il mondo. Non ci interessa affatto cosa c'è sotto il cofano, chi soddisfa la richiesta alla porta, Apache o Nginx, quale bestia sconosciuta, PHP, Python o Ruby lo elabora e genera una risposta, quale archivio dati viene utilizzato: Postgresql , MySQL o MongoDB . La cosa principale è che il server soddisfi la regola principale: ascoltare, comprendere e perdonare la risposta.

Cliente può anche essere qualsiasi cosa che possa formare e inviare una richiesta HTTP. Fino a un certo punto di questo articolo, inoltre, non saremo particolarmente interessati agli obiettivi che il cliente si prefigge inviando questa richiesta, nonché a cosa farà con la risposta. Il client può essere uno script JavaScript in esecuzione nel browser, app mobile, un demone malvagio (o meno) in esecuzione sul server o un frigorifero troppo saggio (ce ne sono già di simili).

Per la maggior parte, parleremo del modo in cui comunicano i due precedenti, in modo tale che si capiscano e nessuno dei due abbia domande.

Filosofia del RIPOSO

REST (Representational state transfer) è stato originariamente concepito come un'interfaccia semplice e univoca per la gestione dei dati, coinvolgendo solo alcune operazioni di base con l'archiviazione diretta in rete (server): recupero dei dati (GET), salvataggio (POST), modifica (PUT / PATCH) e cancellazione (DELETE). Naturalmente, questo elenco è sempre stato accompagnato da opzioni come la gestione degli errori nella richiesta (se la richiesta è stata formulata correttamente), la restrizione dell'accesso ai dati (all'improvviso non dovresti saperlo) e la convalida dei dati in arrivo (all'improvviso hai scritto sciocchezze), in generale tutti gli eventuali controlli che il server esegue prima di esaudire il desiderio cliente.

Inoltre, REST ha una serie di principi architetturali, un elenco dei quali può essere trovato in qualsiasi altro articolo REST. Esaminiamoli brevemente in modo che siano a portata di mano e non debbano andare da nessuna parte:

Indipendenza del server dal client- server e client possono essere istantaneamente sostituiti da altri indipendentemente l'uno dall'altro, poiché l'interfaccia tra loro non cambia. Il server non memorizza gli stati del client.
Unicità degli indirizzi delle risorse- ogni unità di dati (di qualsiasi grado di nidificazione) ha il proprio URL univoco, che, di fatto, è interamente un identificatore univoco della risorsa.

Esempio: OTTIENI /api/v1/users/25/nome

Indipendenza del formato di archiviazione dei dati dal formato della loro trasmissione- il server può supportare più vari formati per trasferire gli stessi dati (JSON, XML, ecc.), ma memorizza i dati nel suo formato interno, indipendentemente da quelli supportati.

Presenza di tutti i metadati necessari nella risposta- oltre ai dati stessi, il server deve restituire i dettagli dell'elaborazione della richiesta, ad esempio messaggi di errore, varie proprietà della risorsa necessarie per ulteriori lavori con esso, ad esempio, il numero totale di voci nella raccolta per visualizzazione corretta navigazione della pagina. Esamineremo i diversi tipi di risorse.

Cosa ci manca

Il REST classico implica il lavoro del client con il server come un archivio dati piatto, mentre non si dice nulla sulla connettività e l'interdipendenza dei dati tra di loro. Tutto questo per impostazione predefinita ricade interamente sulle spalle dell'applicazione client. Tuttavia, le moderne aree tematiche per le quali vengono sviluppati sistemi di gestione dei dati, siano essi servizi sociali o sistemi di marketing su Internet, implicano una relazione complessa tra le entità memorizzate nel database. Supporto per questi collegamenti, ad es. l'integrità dei dati è responsabilità del lato server, mentre il client è solo un'interfaccia per l'accesso a questi dati. Quindi cosa ci manca in REST?

Chiamate di funzione

Per non modificare manualmente i dati ei collegamenti tra di essi, chiamiamo semplicemente una funzione sulla risorsa e "forniamo" i dati necessari come argomento ad essa. Questa operazione non si adatta agli standard REST, non esiste un verbo speciale per essa, il che fa uscire tutti in una volta noi sviluppatori.

L'esempio più semplice– autorizzazione utente. Chiamiamo la funzione login, le passiamo un oggetto contenente le credenziali come argomento e riceviamo una chiave di accesso in risposta. Ciò che accade ai dati sul lato server non ci preoccupa.

Un'altra opzione- creare e interrompere collegamenti tra i dati. Ad esempio, l'aggiunta di un utente a un gruppo. Chiamare un'entità Gruppo funzione addUser, passa l'oggetto come parametro utente, otteniamo il risultato.

E anche ci sono operazioni che non sono direttamente correlate al salvataggio dei dati in quanto tali, ad esempio l'invio di notifiche, la conferma o il rifiuto di qualsiasi operazione (fine del periodo di rendicontazione, ecc.).

Molteplici operazioni

Succede spesso così, e gli sviluppatori client capiranno cosa intendo, che è più conveniente per un'applicazione client creare / modificare / eliminare / più oggetti omogenei contemporaneamente con una richiesta, e per ogni oggetto viene emesso un verdetto lato server possibile. Ci sono almeno diverse opzioni qui: o tutte le modifiche sono state apportate, oppure sono state apportate parzialmente (per alcuni oggetti), oppure si è verificato un errore. Ebbene, ci sono anche diverse strategie: applicare le modifiche solo se hanno successo per tutti, o applicarle parzialmente, o eseguire il rollback in caso di errori, e questo già attiva un meccanismo di transazione a tutti gli effetti.

Per un'API Web che cerca un ideale, vorrei anche portare in qualche modo tali operazioni nel sistema. Proverò a farlo in uno dei sequel.

Query statistiche, aggregatori, formattazione dei dati

Accade spesso che, sulla base dei dati memorizzati sul server, sia necessario ottenere un riepilogo statistico o dati formattati in un modo speciale: ad esempio, per tracciare lato client. In sostanza, si tratta di dati generati su richiesta, più o meno al volo e di sola lettura, quindi ha senso inserirli in una categoria separata. Uno di caratteristiche distintive La statistica, secondo me, è che non hanno un ID univoco.

Sono sicuro che questo non è tutto ciò che potresti incontrare durante lo sviluppo di applicazioni reali e sarò lieto delle tue aggiunte e correzioni.

Varietà di dati

Oggetti

Il tipo di dati chiave nella comunicazione tra il client e il server è un oggetto. Essenzialmente, un oggetto è un elenco di proprietà e dei loro valori corrispondenti. Possiamo inviare un oggetto al server in una richiesta e ottenere il risultato della richiesta come oggetto. In questo caso, l'oggetto non sarà necessariamente un'entità reale memorizzata nel database, almeno nella forma in cui è stato inviato o ricevuto. Ad esempio, le credenziali per l'autorizzazione vengono passate come oggetto, ma non sono un'entità indipendente. Anche gli oggetti archiviati nel database tendono a crescere ulteriori proprietà di natura intra-sistema, ad esempio, date di creazione e modifica, varie etichette e flag di sistema. Le proprietà dell'oggetto possono essere i propri valori scalari o contenere oggetti correlati e collezioni di oggetti, che non fanno parte dell'oggetto. Alcune delle proprietà degli oggetti possono essere modificabili, alcune possono essere di sola lettura e altre possono essere di natura statistica e calcolate al volo (ad esempio, il numero di Mi piace). Alcune proprietà dell'oggetto possono essere nascoste, a seconda dei diritti dell'utente.

Collezioni di oggetti

Parlando di raccolte, intendiamo una sorta di risorsa server che ti consente di lavorare con un elenco di oggetti omogenei, ad es. aggiungere, eliminare, modificare oggetti e selezionarli. Inoltre, la raccolta può teoricamente avere le proprie proprietà (ad esempio, il numero massimo di elementi per pagina) e funzioni (qui sono confuso, ma è successo anche questo).

Valori scalari

Nella sua forma pura, i valori scalari come entità separata erano estremamente rari nella mia memoria. Di solito apparivano come proprietà di oggetti o collezioni e come tali possono essere letti o scritti. Ad esempio, il nome utente può essere recuperato e modificato individualmente con GET /users/1/name . In pratica questa funzione è raramente utile, ma se necessario vorrei che fosse a portata di mano. Ciò è particolarmente vero per le proprietà della raccolta, come il numero di record (con o senza filtro): GET /news/count .

In uno dei seguenti articoli cercherò di classificare queste operazioni e offrire opzioni per possibili richieste e risposte, in base a quelle che ho incontrato nella pratica.

Secondo approccio: il modo giusto

In questa approssimazione, vorrei parlare separatamente degli approcci alla creazione di percorsi univoci per risorse e metodi della tua API Web e di quelle caratteristiche architettoniche dell'applicazione che influenzano l'aspetto di questo percorso e dei suoi componenti.

A cosa pensare quando sei in spiaggia

Versionamento

Prima o poi, qualsiasi sistema operativo inizia a evolversi: svilupparsi, diventare più complesso, ridimensionarsi, modernizzarsi. Per gli sviluppatori dell'API REST, questo è irto principalmente del fatto che è necessario avviare nuove versioni dell'API mentre quelle vecchie funzionano. Qui non sto più parlando di modifiche architettoniche sotto il cofano del tuo sistema, ma del fatto che il formato dei dati stesso e l'insieme delle operazioni con essi stanno cambiando. In ogni caso, il versioning deve essere previsto sia nell'organizzazione iniziale del codice sorgente sia nel principio di costruzione degli URL. Per quanto riguarda l'URL, esistono due dei modi più diffusi per specificare la versione dell'API a cui è rivolta la richiesta. Prefisso del percorso example-api.com/v1/ e controllo delle versioni a livello di sottodominio v1.example-api.com. Puoi usarne uno qualsiasi, a seconda delle necessità e delle necessità.

Autonomia dei componenti

L'API Web di sistemi complessi che supportano più ruoli utente spesso deve essere suddivisa in parti, ognuna delle quali serve una diversa gamma di attività. Infatti, ogni parte può essere un'applicazione indipendente, in esecuzione su diverse macchine fisiche e piattaforme. Nel contesto della descrizione dell'API, non ci importa affatto come il server elabora la richiesta e quali forze e tecnologie sono coinvolte in questo. Per il client API, il sistema è incapsulato. Tuttavia, diverse parti del sistema possono avere funzionalità completamente diverse, come le parti amministrative e utente. E la metodologia di lavoro con le stesse, a quanto pare, le risorse possono differire in modo significativo. Pertanto, tali parti devono essere separate a livello del dominio admin.v1.example-api.com o del prefisso del percorso example-api.com/v1/admin/ . Questo requisito non è obbligatorio e molto dipende dalla complessità del sistema e dal suo scopo.

Formato di scambio dati

Il formato di scambio dati più comodo e funzionale, a mio avviso, è JSON, ma nessuno vieta l'uso di XML, YAML o qualsiasi altro formato che consenta di archiviare oggetti serializzati senza perdere il tipo di dati. Se lo si desidera, è possibile supportare diversi formati di input/output nell'API. È sufficiente utilizzare l'intestazione della richiesta HTTP per indicare il formato di risposta desiderato Accept e Content-Type per indicare il formato dei dati passati nella richiesta. Un altro modo popolare è aggiungere un'estensione all'URL della risorsa, come GET /users.xml , ma questo modo sembra meno flessibile e bello, se non altro perché rende l'URL più pesante ed è più vero per le richieste GET che per tutte operazioni possibili.

Localizzazione e multilinguismo

In pratica, il multilinguismo delle API si riduce molto spesso alla traduzione dei messaggi di servizio e di errore nella lingua richiesta per la visualizzazione diretta all'utente finale. Anche il contenuto multilingue ha un posto dove stare, ma il salvataggio e l'emissione di contenuti in lingue diverse, a mio avviso, dovrebbe essere distinto più chiaramente, ad esempio, se hai lo stesso articolo in lingue diverse, in realtà si tratta di due entità diverse raggruppate nel segno dell'unità del contenuto. Per identificare la lingua prevista, è possibile utilizzare diversi modi. Il più semplice è l'intestazione HTTP standard Accept-Language . Ho visto altri modi, come l'aggiunta del parametro GET language="en" , utilizzando il prefisso del percorso example-api.com/en/ , o anche a livello di nome di dominio en.example-api.com . Mi sembra che la scelta di come specificare le impostazioni locali dipenda dall'applicazione specifica e dalle attività che deve affrontare.

Instradamento interno

Quindi, siamo arrivati ​​al nodo radice della nostra API (o uno dei suoi componenti). Tutti gli ulteriori percorsi passeranno direttamente all'interno dell'applicazione server, in base all'insieme di risorse che supporta.

Percorsi di raccolta

Per specificare il percorso della raccolta, utilizziamo semplicemente il nome dell'entità corrispondente, ad esempio, se si tratta di un elenco di utenti, il percorso sarà /users . Due metodi sono applicabili a una raccolta in quanto tale: GET (ottenendo un elenco limitato di entità) e POST (creando un nuovo elemento). Possiamo utilizzare molti parametri GET aggiuntivi nelle richieste per ottenere elenchi, utilizzati per il paging, l'ordinamento, il filtraggio, la ricerca, ecc., ma devono essere facoltativi, ad es. questi parametri non devono essere passati come parte del percorso!

Elementi della collezione

Per fare riferimento a un elemento specifico della raccolta, utilizziamo il suo identificatore univoco /users/25 nel percorso. Questo è il percorso unico per raggiungerlo. Per lavorare con un oggetto, sono applicabili i metodi GET (ottenimento di un oggetto), PUT / PATCH (modifica) e DELETE (eliminazione).

Oggetti unici

Molti servizi hanno oggetti univoci per l'utente corrente, come il profilo/profilo dell'utente corrente o le impostazioni/impostazioni personali. Naturalmente, da un lato, questi sono elementi di una delle raccolte, ma sono il punto di partenza per l'utilizzo della nostra API Web da parte dell'applicazione client e inoltre consentono molto di più vasta gamma operazioni sui dati. Allo stesso tempo, la raccolta che memorizza le impostazioni dell'utente potrebbe non essere affatto disponibile per motivi di sicurezza e riservatezza dei dati.

Proprietà di oggetti e collezioni

Per accedere direttamente a una qualsiasi delle proprietà di un oggetto, è sufficiente aggiungere il nome della proprietà al percorso dell'oggetto, ad esempio ottenere il nome utente /users/25/name . I metodi GET (get value) e PUT/PATCH (value change) sono applicabili alla proprietà. Il metodo DELETE non è applicabile perché una proprietà è una parte strutturale di un oggetto, come un'unità formalizzata di dati.

Nella parte precedente abbiamo parlato di come le collezioni, come gli oggetti, possono avere proprie proprietà. Nella mia memoria, solo la proprietà count mi è stata utile, ma la tua applicazione può essere più complessa e specifica. I percorsi alle proprietà della raccolta sono costruiti secondo lo stesso principio delle proprietà dei loro elementi: /users/count . Per le proprietà della raccolta, è applicabile solo il metodo GET (ottenimento di una proprietà). una raccolta è solo un'interfaccia per accedere a un elenco.

Collezioni di oggetti correlati

Un tipo di proprietà dell'oggetto può essere oggetti correlati o raccolte di oggetti correlati. Tali entità, di regola, non sono proprietà proprie dell'oggetto, ma solo riferimenti alle sue relazioni con altre entità. Ad esempio, un elenco di ruoli che sono stati assegnati all'utente /users/25/roles . Parleremo in dettaglio dell'utilizzo di oggetti e raccolte nidificati in una delle parti seguenti, ma in questa fase è sufficiente per noi potervi accedere direttamente, come qualsiasi altra proprietà di un oggetto.

Funzioni oggetto e collezione

Per creare un percorso a un'interfaccia di chiamata di funzione su una raccolta o un oggetto, utilizziamo lo stesso approccio utilizzato per l'accesso a una proprietà. Ad esempio, per l'oggetto /users/25/sendPasswordReminder o per la raccolta /users/disableUnconfirmed. Per le chiamate di funzione, usiamo comunque il metodo POST. Come mai? Permettetemi di ricordarvi che nel classico REST non esiste un verbo speciale per chiamare le funzioni, e quindi dovremo usarne uno di quelli esistenti. A mio parere, il metodo POST è il più adatto a questo. ti consente di passare gli argomenti necessari al server, non è idempotente (restituisce lo stesso risultato quando si accede più volte) ed è il più astratto in semantica.

Spero che tutto si adatti più o meno al sistema 🙂 Nella parte successiva parleremo più dettagliatamente di richieste e risposte, dei loro formati e dei codici di stato.

Approccio tre: richieste e risposte

In precedenti approssimazioni, ho parlato di come è nata l'idea di raccogliere e generalizzare l'esperienza esistente sviluppo web API. Nella prima parte, ho provato a descrivere con quali tipi di risorse e operazioni su di esse abbiamo a che fare durante la progettazione di un'API Web. La seconda parte ha toccato i problemi della creazione di URL univoci per l'accesso a queste risorse. E in questa approssimazione, proverò a descrivere le possibili opzioni per richieste e risposte.

Risposta universale

Abbiamo già detto che il formato specifico di comunicazione tra server e client può essere qualsiasi a discrezione dello sviluppatore. Per me, il più conveniente e visivo sembra Formato JSON, sebbene un'applicazione reale possa supportare più formati. Per ora, concentriamoci sulla struttura e sugli attributi richiesti dell'oggetto risposta. Sì, avvolgeremo tutti i dati restituiti dal server in un contenitore speciale - oggetto di risposta generico, che conterrà tutte le informazioni di servizio necessarie per la sua ulteriore elaborazione. Allora, qual è questa informazione:

Successo - indicatore del successo della richiesta

Per capire immediatamente se la richiesta è andata a buon fine quando si riceve una risposta dal server e passarla al gestore appropriato, è sufficiente utilizzare l'indicatore di successo "successo". La risposta del server più semplice, che non contiene dati, sarebbe simile a questa:

POST /api/v1/articles/22/publish ( "successo": true )

Errore: informazioni sull'errore

Se la richiesta fallisce - parleremo dei motivi e dei tipi di risposte negative del server poco dopo - l'attributo "error" viene aggiunto alla risposta, contenente il codice di stato HTTP e il testo del messaggio di errore. Si prega di non confondere con i messaggi su errori di convalida dati per campi specifici. È più corretto, a mio avviso, restituire il codice di stato nell'intestazione della risposta, ma ho anche incontrato un altro approccio: restituire sempre lo stato 200 (successo) nell'intestazione e inviare dettagli e possibili dati di errore nel corpo della risposta.

GET /api/v1/user ( "success": false, "error": ( "code" : 401, "message" : "Autorizzazione fallita" ) )

Dati: dati restituiti dal server

La maggior parte delle risposte del server sono progettate per restituire dati. A seconda del tipo di richiesta e del suo successo, il set di dati previsto sarà diverso, tuttavia l'attributo "dati" sarà presente nella stragrande maggioranza delle risposte.

Esempio di dati restituiti in caso di successo. In questo caso, la risposta contiene l'oggetto utente richiesto.

GET /api/v1/user ( "success": true, "data": ( "id" : 125, "email" : " [e-mail protetta]", "nome" : "John", "cognome" : "Smith", ) )

Esempio di dati restituiti in caso di errore. In questo caso, contiene nomi di campo e messaggi di errore di convalida.

PUT /api/v1/user ( "success": false, "error": ( "code" : 422, "message" : "Convalida non riuscita" ) "data": ( "email" : "L'e-mail non può essere vuota. ", ) )

Impaginazione: informazioni necessarie per organizzare l'impaginazione

Oltre ai dati effettivi, nelle risposte che restituiscono set di elementi di raccolta, devono essere presenti informazioni sull'impaginazione in base ai risultati della query.

Il set minimo di valori per l'impaginazione è costituito da:

  • numero totale di record;
  • numero di pagine;
  • numero di pagina corrente;
  • numero di record per pagina;
  • il numero massimo di record per pagina supportati dal lato server.

Alcuni sviluppatori di API Web includono anche una serie di collegamenti già pronti alle pagine adiacenti, nonché la prima, l'ultima e le pagine correnti nell'impaginazione.

GET /api/v1/articles Risposta: ( "success": true, "data": [ ( "id" : 1, "title" : "Cosa interessante", ), ( "id" : 2, "title" : "Testo noioso", ) ], "pagination": ( "totalRecords" : 2, "totalPages" : 1, "currentPage" : 1, "perPage" : 20, "maxPerPage" : 100, ) )

Lavora sugli errori

Come accennato in precedenza, non tutte le richieste all'API Web hanno esito positivo, ma anche questo fa parte del gioco. Il sistema di segnalazione degli errori è un potente strumento che facilita il lavoro del cliente e guida l'applicazione del cliente sulla strada giusta. La parola "errore" in questo contesto non è del tutto appropriata. La parola è più appropriata qui. eccezione, poiché in effetti la richiesta è stata ricevuta con successo, analizzata e le viene restituita una risposta adeguata, spiegando perché la richiesta non può essere soddisfatta.

Quali sono le potenziali cause delle eccezioni che ricevi?

500 Errore interno del server: tutto è rotto, ma lo ripareremo presto

Questo è esattamente il caso in cui il problema si è verificato sul lato del server stesso e l'applicazione client può solo sospirare e notificare all'utente che il server è stanco e si è sdraiato per riposare. Ad esempio, la connessione al database è persa o c'è un bug nel codice.

400 Richiesta errata - e ora tutto è rotto

La risposta è esattamente l'opposto della precedente. Restituito quando l'applicazione client invia una richiesta che, in linea di principio, non può essere elaborata correttamente, non contiene parametri obbligatori o presenta errori di sintassi. Questo di solito viene risolto rileggendo la documentazione dell'API web.

401 Non autorizzato - straniero, identificarsi

Per accedere a questa risorsa è necessaria l'autorizzazione. Ovviamente la presenza dell'autorizzazione non garantisce che la risorsa diventi disponibile, ma senza autorizzazione non lo saprai con certezza. Si verifica, ad esempio, quando si tenta di accedere alla parte privata dell'API o quando il token corrente scade.

403 Proibito - non puoi venire qui

La risorsa richiesta esiste, ma l'utente non dispone di diritti sufficienti per visualizzarla o modificarla.

404 Non trovato - nessuno vive a questo indirizzo

Tale risposta viene restituita, di norma, in tre casi: il percorso della risorsa non è corretto (errato), la risorsa richiesta è stata cancellata e ha cessato di esistere, i diritti dell'utente corrente non gli consentono di conoscere l'esistenza della risorsa richiesta. Ad esempio, durante la navigazione in un elenco di prodotti, uno di questi è improvvisamente passato di moda ed è stato rimosso.

405 Metodo non consentito

Questo tipo di eccezione è direttamente correlato al verbo utilizzato nella richiesta (GET, PUT, POST, DELETE) che, a sua volta, indica l'azione che stiamo tentando di eseguire con la risorsa. Se la risorsa richiesta non supporta l'azione specificata, il server lo dice direttamente.

422 Entità non elaborabile - correggi e invia di nuovo

Una delle eccezioni più utili. Restituito ogni volta che ci sono errori logici nei dati della richiesta. Per dati della richiesta si intende un insieme di parametri e i relativi valori passati dal metodo GET o campi di un oggetto passati nel corpo della richiesta dai metodi POST, PUT e DELETE. Se i dati non sono convalidati, il server nella sezione "dati" restituisce un rapporto su quali parametri non sono validi e perché.

Il protocollo HTTP supporta molto Di più vari codici di stato per tutte le occasioni, ma in pratica sono usati raramente e nel contesto dell'API web non sono di alcuna utilità pratica. Nella mia memoria, non ho dovuto andare oltre l'elenco di eccezioni di cui sopra.

Richieste

Ottenere gli elementi di una collezione

Una delle richieste più frequenti è quella di ottenere gli elementi di una collezione. Feed informativi, elenchi di prodotti, tabelle informative e statistiche varie e molto altro vengono visualizzati dall'applicazione client accedendo alle risorse di raccolta. Per fare questa richiesta, accediamo alla raccolta utilizzando il metodo GET e passando parametri aggiuntivi nella stringa di query. Come abbiamo già indicato in precedenza, come risposta, ci aspettiamo di ricevere una matrice di elementi omogenei della raccolta e le informazioni necessarie per l'impaginazione - caricando la continuazione dell'elenco o la sua pagina specifica. Il contenuto della selezione può essere limitato in modo speciale e ordinato passando opzioni aggiuntive. Saranno discussi ulteriormente.

Impaginazione

pagina- parametro indica quale pagina deve essere visualizzata. Se questo parametro non viene passato, viene visualizzata la prima pagina. Dalla prima risposta riuscita del server, sarà chiaro quante pagine ha la raccolta con i parametri di filtro correnti. Se il valore supera il numero massimo di pagine, è ragionevole restituire un errore 404 non trovato.

OTTIENI /api/v1/news?page=1

per pagina- indica il numero desiderato di elementi per pagina. In genere, l'API ha un proprio valore predefinito che restituisce il campo perPage nella sezione paginazione, ma in alcuni casi consente di aumentare questo valore entro limiti ragionevoli fornendo un valore maxPerPage massimo:

OTTIENI /api/v1/news?perPage=100

Ordina i risultati

Spesso, i risultati di una selezione devono essere ordinati in ordine crescente o decrescente in base ai valori di determinati campi che supportano l'ordinamento comparativo (per i campi numerici) o alfabetico (per i campi stringa). Ad esempio, dobbiamo ordinare l'elenco degli utenti per nome o dei prodotti per prezzo. Inoltre, possiamo impostare la direzione di ordinamento dalla A alla Z o nella direzione opposta e diversa per i diversi campi.

ordina per- Esistono diversi approcci per passare dati sull'ordinamento complesso nei parametri GET. Qui è necessario specificare chiaramente l'ordinamento e la direzione.

Alcune API suggeriscono di farlo come una stringa:

OTTIENI /api/v1/products?sortBy=name.desc,price.asc

Altre opzioni suggeriscono di utilizzare un array:

OTTIENI /api/v1/prodotti? sortBy=nome& sortBy=desc& sortBy=prezzo& sortBy=asc

In generale, entrambe le opzioni sono equivalenti, poiché trasmettono le stesse istruzioni. Secondo me l'opzione con un array è più versatile, ma qui, come si suol dire, il gusto e il colore ...

Semplice filtraggio per valore

Per filtrare la selezione in base al valore di un campo, nella maggior parte dei casi è sufficiente passare il nome del campo e il valore richiesto come parametro di filtro. Ad esempio, vogliamo filtrare gli articoli per ID autore:

OTTIENI /api/v1/articles?authorId=25

Opzioni di filtraggio sofisticate

Molte interfacce richiedono sistemi di filtraggio e ricerca più complessi. Elencherò le opzioni di filtro principali e più comuni.

Filtraggio per limiti superiore e inferiore utilizzando operatori di confronto da (maggiore o uguale a), superiore (maggiore di), a (minore o uguale a), inferiore (minore di). Si applica ai campi i cui valori sono classificabili.

OTTIENI /api/v1/products?price=500&price=1000

Filtraggio per più valori possibili dall'elenco. Applicato ai campi, imposta valori possibili che è limitato, ad esempio, un filtro da diversi stati:

OTTIENI /api/v1/products?status=1&status=2

Filtraggio per corrispondenza di stringa parziale. Si applica ai campi che contengono dati di testo o dati che possono essere trattati come testo, ad esempio numeri di prodotto, numeri di telefono e così via.

GET /api/v1/users?name=Giovanni GET /api/v1/products?code=123

Filtri con nome

In alcuni casi, quando vengono spesso utilizzati determinati insiemi di parametri di filtraggio e sono intesi dal sistema come qualcosa di integrale, soprattutto se influenzano la meccanica interna, spesso complessa, del campionamento, è consigliabile raggrupparli nei cosiddetti filtri denominati. È sufficiente passare il nome del filtro nella richiesta e il sistema costruirà automaticamente la selezione.

OTTIENI /api/v1/products?filters=recommended

I filtri con nome possono anche avere i propri parametri.

OTTIENI /api/v1/products?filters=kidds

In questa sottosezione, ho provato a parlare delle opzioni e dei modi più popolari per ottenere il campione richiesto. Molto probabilmente, nella tua pratica ci saranno molti più esempi e sfumature riguardo a questo argomento. Se hai qualcosa da aggiungere al mio materiale, sarò solo felice. Nel frattempo, il post è già cresciuto fino a raggiungere una solida scala, quindi analizzeremo altri tipi di richieste nella prossima approssimazione.

6.1 Metodo CheckDimensions

Sintassi:

Booleano Controlla le dimensioni(Dimensioni DimensioniLista,

Lunghezza di galleggiamento,

Larghezza di galleggiamento,

Altezza di galleggiamento,

Peso di galleggiamento,

Commento esterno)

Opzioni:

Nome del parametro Input Output Tipo di Descrizione
DimensioniLista ingresso Dimensioni Vettore
peso complessivo
caratteristiche del prodotto
Lunghezza giorno libero galleggiante Lunghezza pacco
Larghezza giorno libero galleggiante Larghezza pacco
Altezza giorno libero galleggiante Altezza pacco
Il peso giorno libero galleggiante Peso del pacco
Commento giorno libero galleggiante Descrizione del testo quando superato
valori limite di peso complessivo
caratteristiche

Descrizione:

L'elenco delle caratteristiche di peso e dimensioni di tutte le merci viene passato al metodo
(Elenco dimensioni). Dopo il calcolo, i parametri di output Lunghezza, Larghezza, Altezza (lunghezza,
larghezza e altezza, rispettivamente) vengono riempite con le dimensioni del lotto, dopo averle risolte
problema di "impilamento ottimale", e al parametro Weight viene passato il peso totale di tutti
merci, esclusi i materiali di imballaggio. Nel caso in cui le dimensioni della spedizione
superano i valori limite, al parametro Comment viene passata una descrizione testuale
incongruenze.

Valore di ritorno: Il metodo restituisce un True if booleano
le caratteristiche di peso complessivo non superano i valori limite e la consegna
possibile almeno uno modo accessibile, altrimenti Falso. Presumibilmente dato
il metodo può essere utilizzato sul lato client per la valutazione online
la fondamentale possibilità di invio di un ordine e la tempestiva accettazione dell'eventuale
decisioni se questo non è possibile.

6.1.1 Un esempio di chiamata al metodo CheckDimensions



// Supponiamo che ci siano 2 posizioni nel carrello e devi controllare se supera
restrizioni sulle dimensioni e sul peso consentiti
aplix.Dimensions Dimensioni = new aplix.Dimensions;
aplix.DimensionsItem;

Item.Length = 0.130f;
Item.Width = 0.100f;
Item.Height = 0.001f;
Item.Weight = 0.1f;
Item.Qty = 2;
Dimensioni = articolo;
Item = new aplix.Dimensions();
Item.Length = 0.1331f;
Item.Width = 0.0998f;
Item.Height = 0.0788f;
Item.Weight = 0.575f;
Item.Qty = 1;
Dimensioni = articolo;
// Parametri di output
galleggiante Lunghezza;
galleggiante Larghezza;
galleggiante Altezza;
galleggiante Peso;
stringa Commento;
// Esegue il controllo del peso
bool Risultato = ws.CheckDimenshions(Dimensions, out Length, out Width, out Height, outWeight, out Comment);
// Visualizzazione del risultato
Response.Write("Risultato: " + Risultato.ToString() + "");
Response.Write("Lunghezza: " + Lunghezza.ToString() + "");
Response.Write("Larghezza: " + Larghezza.ToString() + "");
Response.Write("Altezza: " + Altezza.ToString() + "");
Response.Write("Peso: " + Peso.ToString() + "");
Response.Write("Peso: "+Commento+"");

6.2 Metodo CalculateShippingCost

Sintassi:
Lungo Calcola il costo di spedizione(stringa NumeroOrdine,
float Costo dichiarato,
Merci Merci,
Indirizzo,
Byte TypeOfSeal,
Imballaggio robusto booleano,
Booleano Contrassegno,
Out DeliveryType Tipi,
Out string Commenti)Parametri:

Nome del parametro Input Output Tipo di Descrizione
Numero d'ordine ingresso corda Numero d'ordine, se noto nel sistema
consumatore. Se è dato, allora il calcolo
in futuro sarà legato all'ordine.
costo dichiarato ingresso galleggiante Il valore dichiarato della spedizione. Sul

assicurazione.
Merce ingresso Merce Elenco dei beni array di strutture
(Codice venditore,
Nome,
Lunghezza,
Larghezza, Altezza, Peso, Quantità)
Indirizzo ingresso Indirizzo Indirizzo del destinatario (struttura: postale
indice,
Regione,
La zona,
Città,
Località, strada, casa, alloggio,
Kartira)
Tipo di sigillo ingresso byte Opzione
foche,
possibile
valori:1 Non richiesto

2 pluriball

3 Riempitivo

Confezione robusta ingresso Booleano È necessario avere un rigido
pacchetto
Pagamento alla consegna ingresso Booleano È richiesto il pagamento in contrassegno
tipi giorno libero tipo di consegna
Commenti giorno libero tipo di consegna Elenco delle opzioni di spedizione disponibili

Descrizione:

In base ai parametri forniti, il metodo restituisce un elenco di opzioni di consegna disponibili
(parametro di output Tipi) come matrice di strutture<Идентификатор способа доставки, Наименование способа доставки, Себестоимость доставки, Страховую премию, Затраты на упаковку и маркировку, Адрес нахождения почтового отделения, либо точки самовывоза, Режим работы почтового отделения, либо точки самовывоза, Минимальное количество дней доставки, Максимальное количество дней доставки, Доп.информация>. Se ci sono eccezioni durante il calcolo, allora
una descrizione dell'errore verrà restituita nel parametro Commenti.

Valore di ritorno:

Il metodo restituisce un identificatore univoco del calcolo, in base al quale in futuro
sarà possibile richiedere l'evidenziazione dei costi del materiale e della manodopera utilizzando il metodo
OttieniDettagliCosto.

6.2.1 Un esempio di chiamata al metodo CalculateShippingCost



ws.Credentials = new NetworkCredential("test", "test");


Indirizzo.Indice = "684005";


Address.City = "Yelizovo città";

Indirizzo.Casa = "16";


aplix.GoodsItem;
Item = new aplix.Goods();
Item.SKU = "216293";

Item.Length = 0.130f;
Item.Width = 0.100f;
Item.Height = 0.001f;
Item.Weight = 0.1f;
Item.Qty = 2;
Merce = articolo;
Item = new aplix.Goods();
Item.SKU = "499687";

Item.Length = 0.1331f;
Item.Width = 0.0998f;
Item.Height = 0.0788f;
Item.Weight = 0.575f;
Item.Qty = 1;
Merce = articolo;
// Inserisci i parametri per la calcolatrice
stringOrderNumber="1234567890";
float CostoDichiarato = 36370;
sbyte TypeOfSeal = 1;
bool SturdyPackaging = vero;
bool CashOnDelivery = falso;
aplix.DeliveryType Tipi; stringa Commenti;
// chiamata alla calcolatrice
long Status = ws.CalculateShippingCost(OrderNumber, DeclaredCost, Goods, Address,TypeOfSeal, SturdyPackaging,CashOnDelivery, out Types, out Comments);
//Visualizzazione dei risultati
Response.Write("ID calcolo: "+Stato.ToString()+"
");
Response.Write("Ulteriori informazioni sul calcolo: " + Commenti + "
");
Risposta.Scrivi(@"
");
foreach (tipo aplix.DeliveryType in Tipi) (
Response.Write(""+ " "+ " "+ " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " "); )
Risposta.Scrivi("
































ID tipo TipoNome TipoDescrizione costo Assicurazione Tariffa postale costo di preparazione Indirizzo Tempo di lavoro MinPeriod MaxPeriod Informazioni aggiuntive
" + type.TypeId.ToString() + " " + tipo.NomeTipo + " " + tipo.TipoDescrizione + " " + type.Cost.ToString() + " " + type.Insurance.ToString() + " " + type.PostalRate.ToString() + " " + type.PreparingCost.ToString() + " " + digitare.Indirizzo + " " + type.Worktime + " " + type.MinPeriod.ToString() + " " + tipo.MaxPeriod.ToString() + " " + type.AdditionalInformation + "

");
}

6.3 Metodo PushOrder

Sintassi:
Lungo ordine di spinta(
id,
numero,
Data,
cliente,
costo dichiarato,
Somma da pagare,
ID tipo di consegna,
TipoOfseal,
Imballaggio robusto,
attività,
merce,
data di consegna,
InizioOraConsegna,
OraFineConsegna,
commento,
spedizione,
marcatore)
Opzioni:

Nome del parametro Input Output Tipo di Descrizione
ID ingresso Corda ID ordine nel sistema
consumatore ( valore unico)
numero ingresso Corda Numero d'ordine nel sistema del cliente
(verrà stampato nei commenti)
quando si contrassegnano le spedizioni)
Data ingresso appuntamento La data dell'ordine nel sistema del consumatore (sarà
stampa nei commenti
marcatura delle spedizioni
cliente ingresso cliente Informazioni sull'acquirente, struttura
costo dichiarato ingresso galleggiante Il valore dichiarato della spedizione. Sul
verrà emesso l'importo indicato
assicurazione.
ImportoBeP
aiuto
ingresso galleggiante Somma
a
pagamento.
Se una
ordine
pagamento anticipato quindi 0.
DeliveryTypeId ingresso int ID metodo selezionato
consegna.
Tipo di sigillo ingresso int Opzione
foche,
possibile
i valori:
1Non richiesto
2 pluriball
3riempitivo
Imballaggio robusto ingresso Booleano È necessario avere un rigido
pacchetto
Attività ingresso Booleano Rilevanza dell'ordine. Vero - se l'ordine
valido, falso – se l'ordine viene annullato.
Merce ingresso Merce Elenco prodotti
Data di consegna ingresso appuntamento Data di consegna, da compilare se selezionata
consegna espressa
StartTimeDeliv
ery
ingresso int Lista dei desideri
volta
consegna
"DA",

consegna
FineOraConsegna ingresso int Tempo di consegna desiderato "A",
compilato se viene selezionato il corriere
consegna
Commento ingresso Corda Commento all'ordine
ID mittente ingresso Corda Identificatore
mittente,
è pieno
Se
presso la controparte
diversi negozi online
marcatore ingresso Corda Indicatore d'ordine, compilato se
le spedizioni sono etichettate
sito web

Descrizione:
Il metodo inserisce le informazioni sull'ordine nel sistema dell'appaltatore. consumatore di sistema
trasmette il numero e la data dell'ordine, un identificatore univoco dell'ordine, informazioni su
il destinatario, compreso il suo indirizzo e numero di telefono, il valore dichiarato, l'importo dell'imposta
pagamento, se del caso, la composizione della merce attaccata, il tipo di imballaggio e la scelta
metodo di consegna e dettagli.

Valore di ritorno:
Il metodo restituisce un identificatore univoco dell'ordine nel sistema del contraente.

6.3.1 Esempio di chiamata al metodo PushOrder


aplix.Delivery ws = new aplix.Delivery();
ws.Credentials = new NetworkCredential("test", "test");
// Prepara la struttura "Invia destinatario".
aplix.Cliente = new aplix.Cliente();
// 684005, Territorio di Kamchatka, distretto di Elizovsky, città di Elizovo, via Leninskaya, casa n. 16
aplix.Address Indirizzo = new aplix.Address();
Indirizzo.Indice = "684005";
Indirizzo.Regione = "Kamchatsky Krai";
Address.District = "Distretto Elizovsky";
Address.City = "Yelizovo città";
Address.Street = "Via Leninskaya";
Indirizzo.Casa = "16";
Cliente.Indirizzo = Indirizzo;
ID.cliente = " [e-mail protetta]";
Customer.Name = "Sergey";
Cliente.Email = " [e-mail protetta]";
Cliente.Telefono = "+7(916)975-53-54";
// Compila i parametri dell'ordine
ID stringa = "2013-1234567890"; // Identificatore univoco dell'ordine nel sistema del cliente
stringa Numero = "1234567890"; // Numero d'ordine nel sistema del cliente
DateTime Date = new DateTime(2013, 08, 30);
float CostoDichiarato = 36350.0f; // Valore dichiarato
float AmountToBePaid = 0; // Nessun pagamento in contrassegno
int DeliveryTypeId = 4; // CEM
sbyte TypeOfSeal = 2; // Pluriball
bool SturdyPackaging = vero; // Imballaggio rigido (per oggetti fragili)
bool Attività = vero; // Il documento è aggiornato
// Supponiamo che l'ordine sia composto da 2 articoli
aplix.Goods Merci = new aplix.Goods;
aplix.GoodsItem;
Item = new aplix.Goods();
Item.SKU = "216293";
Item.Name = "SDXC 64Gb Class 10 Transcend";
Item.Length = 0.130f;
Item.Width = 0.100f;
Item.Height = 0.001f;
Item.Weight = 0.1f;
Item.Qty = 1;
Articolo.Prezzo = 2080.0f;
Item.VATRate = "IVA18";
Merce = articolo;
Item = new aplix.Goods();
Item.SKU = "499687";
Item.Name = "Canon EOS 650D Kit Tamron AF 18-270 mm nero";
Item.Length = 0.1331f;
Item.Width = 0.0998f;
Item.Height = 0.0788f;
Item.Weight = 0.575f;
Item.Qty = 1;
Articolo.Prezzo = 34270.0f;
Item.VATRate = "IVA18";
Merce = articolo;
DateTime DeliveryDate = new DateTime(2013, 09, 05); //Consegna il 05 09 2013
int StartTimeDelivery = 10; // intervallo di consegna da 10
int EndTimeDelivery = 14; // fino a 14
string Comment = "Ordine di prova";
//Trascina l'ordine nel sistema
long OrderId = ws.PushOrder(ID, Number, Date, Customer, DeclaredCost, AmountToBePaid,DeliveryTypeId, TypeOfSeal, SturdyPackaging, Activity, Goods, DeliveryDate, StartTimeDelivery,EndTimeDelivery, Comment, "", "");
Response.Write("ID ordine: " + OrderId.ToString() + "
");

6.4 Metodo GetDetailsOfCost

Sintassi:        DetailsOfCostList GetDetailsOfCost (ID, TypeId) Parametri:

Input Output
Tipo di
Descrizione

ingresso
Lungo
ID calcolo (valore univoco) ottenuto chiamando il metodo CalculateShippingCost

ingresso
int

Nome del parametro
ID ID tipo

Descrizione: il metodo restituisce un elenco dettagliato dei costi per l'etichettatura e l'imballaggio di una spedizione per l'ID fatturazione e l'ID opzione di consegna specificati. Valore di ritorno: Il metodo restituisce una matrice di strutture

Ogni elemento dell'array contiene una descrizione del costo, della quantità, del prezzo e del costo.

6.4.1 Esempio di chiamata al metodo GetDetailsOfCost


aplix.Delivery ws = new aplix.Delivery();
ws.Credentials = new NetworkCredential("test", "test");
longID = 168; // ID calcolo ricevuto dal metodo CalculateShippingCost
int TypeId = 3; // Consegna postale

aplix.DetailsOfCost Dettagli = ws.GetDetailsOfCost(ID, TypeId);
//Visualizzazione dei risultati
Response.Write("ID calcolo: " + ID.ToString() + "
");
Response.Write("ID metodo di consegna: " + TypeId.ToString() + "
");
Risposta.Scrivi(@"


");
foreach(aplix.DetailsOfCost DetailOfCost in Dettagli)
{
Response.Write("" + " " + " " + " " + " " + " ");
}
Risposta.Scrivi("















Descrizione prezzo Qtà costo
" + DettaglioCosto.Descrizione + " " + DetailOfCost.Price.ToString() + " " + DetailOfCost.Qty.ToString() + " " + DettaglioOfCost.Cost.ToString() + "

");

6.5 Metodo PushReestr

Sintassi: Lungo PushOrder (ID, Number, Date, DateOfShipment, IDs) Parametri:

Input Output
Tipo di
Descrizione

ingresso
Corda
ID registro sul sistema consumer (valore univoco)

ingresso
Corda
Identificatore dell'opzione di consegna per la quale si desidera ottenere i dettagli

ingresso
appuntamento
Data di registrazione (verrà stampata nei certificati di accettazione delle spedizioni)

ingresso
appuntamento
Data prevista per il trasferimento degli articoli all'appaltatore

ingresso
Corda
Una matrice di ID ordine inclusi in questo registro

Nome del parametro
ID numero Data Data di spedizione ID

Descrizione: il metodo inserisce informazioni sul registro nel sistema dell'esecutore. Il sistema-consumatore trasmette all'esecutore testamentario il numero e la data del registro, l'identificativo univoco del registro, la data prevista di consegna degli articoli. Valore di ritorno: Il metodo restituisce un identificatore univoco del registro nel sistema dell'esecutore.

6.5.1 Esempio di chiamata al metodo PushReestr


aplix.Delivery ws = new aplix.Delivery();
ws.Credentials = new NetworkCredential("test", "test");
// Elenco degli ID ordine inclusi in questo registro
string ID=("2013-1234567890", "2013-1234567891");
// Identificatore univoco del registro nel sistema client
ID stringa = "2013-r12345";
// Numero di registro nel sistema client
stringa Numero = "r12345";
// Data di formazione del registro nel sistema del cliente
DateTime Date = new DateTime(2013, 10, 22);
// Data stimata di trasferimento degli ordini per la consegna
DateTime DateOfShipment = new DateTime(2013, 10, 23);
// Ottieni i dettagli del calcolo
long ReestID = ws.PushReestr(ID, Number, Date, DateOfShipment, IDs);
//Visualizzazione dei risultati
Response.Write("ID registro: " + ReestID.ToString() + "
");

6.6 Metodo GetTrackNumbers

Sintassi: data/ora Ottieni i numeri di traccia(DateOfLastGetting, TrackNumbers) Parametri:

Input Output
Tipo di
Descrizione

ingresso
appuntamento
Data dell'ultima ricezione riuscita dei numeri di traccia. Il parametro viene utilizzato per ridurre la quantità di dati trasferiti e non per duplicare i dati caricati in precedenza.

ingresso
numero di spedizione
Array di numeri di traccia per gli ordini

Nome del parametro
DateOfLastGetting Numeri di traccia

Descrizione: il metodo restituisce un elenco di numeri di traccia associati agli ordini per il periodo da DateOfLastGetting a ora attuale. Il risultato viene inserito nel parametro di output TrackNumbers. La proprietà Activity è impostata su true se il numero della traccia è aggiornato, su false in caso contrario. Ci sono situazioni in cui a una spedizione viene assegnato un numero di traccia, e dopo qualche secondo numero di traccia, in questo caso il numero di traccia inizialmente assegnato diventa irrilevante. Valore di ritorno: Il metodo restituisce la data e l'ora per cui i dati caricati sono rilevanti. Valore dato deve essere utilizzato la volta successiva che il metodo GetTrackNumbers viene chiamato nel parametro DateOfLastGetting.

6.6.1 Esempio di chiamata al metodo GetTrackNumbers


aplix.Delivery ws = new aplix.Delivery();
ws.Credentials = new NetworkCredential("test", "test");
// Data dell'ultima ricezione riuscita delle tracce
DateTime DateOfLastGetting = new DateTime(2013, 08, 01);
aplix.TrackNumber TrackNumbers;
// Ottieni un elenco di numeri di traccia
DateTime NewDateOfLastGetting = ws.GetTrackNumbers(DateOfLastGetting, out TrackNumbers);
//Visualizzazione dei risultati
Response.Write("NewDateOfLastGetting: " + NewDateOfLastGetting.ToString() +"
");
Risposta.Scrivi(@"


");
foreach (aplix.TrackNumber TrackNumber in TrackNumbers)
{
Response.Write("" + " " + " " + " " + " ");
}
Risposta.Scrivi("













ID ordine numero di spedizione Attività
" + TrackNumber.OrderID.ToString() + " " + Numero traccia.Numero + " "+Numero traccia.Attività+"

");

API (Application Programming Interface) è certa rappresentazione dati per l'interazione tra le applicazioni. In un caso particolare, il server può fungere da applicazione di risposta. L'API è un formato descritto a cui devono conformarsi entrambe le parti dello scambio di dati.

La tecnologia di varie API è un insieme di metodi di interazione. Il sistema API in una forma o nell'altra è presentato ovunque. Ad esempio, abbiamo tra le mani uno smartphone con un'applicazione per l'acquisto di biglietti. Al livello "più alto" vediamo la parte grafica dell'applicazione con i campi di inserimento dati. Richiediamo voli lungo la rotta per un giorno specifico e cosa succede in quel momento:

  1. L'applicazione mobile genera una richiesta al server. La richiesta è formata in un certo formato. Ad esempio: Partenza:MoscaDME,Arrivo:AmsterdamAMS,Data:01-01-2017,Posti:2,Classe:Economy. Questa riga contiene un formato rigoroso - Intestazione:Valore, tutti i valori separati da virgole, campi obbligatori Partenza, Arrivo e Data, se non vengono specificati altri dati, saranno per impostazione predefinita: Posti:1, Classe:Economia.
  2. Il server della compagnia aerea riceve questa richiesta e il programma capisce che è necessario trovare voli e prezzi.
  3. Il server accede al database in SQL, che è anche una rappresentazione privata dell'API
  4. Il database accede al file tramite l'API del file system
  5. Il file system accede al disco rigido tramite il suo protocollo API.

Puoi continuare ad approfondire, ma è chiaro che qualsiasi attività di programmazione sta costruendo una gerarchia API.

Oggi, in una forma o nell'altra, tutte le informazioni in formato informatico sono rappresentate da API.

Sviluppiamo sistemi API per il livello superiore, dove il consumatore successivo è l'applicazione client.

Classificazione dei tipi di API

A seconda dell'attività da risolvere, i protocolli di trasferimento API possono essere sia standardizzati che in formato proprio. I protocolli standardizzati più comunemente usati, questo consente agli sviluppatori di utilizzare moduli già pronti per la loro elaborazione, il che riduce i tempi di sviluppo di un'applicazione. Vengono utilizzati vari tipi specifici per ottenere determinati vantaggi, come la riduzione del traffico, la velocità di riconoscimento dei comandi e, in alcuni casi - questa è l'unica possibilità - lo sviluppo di un proprio formato, ad esempio la trasmissione di video con una componente effemerica.

In base al tipo di informazioni trasmesse, l'API è suddivisa nei seguenti formati:

  • Protocolli API standard
    • Testo
  • Binario
    • in linea
    • personale

In base al tipo di interazione client-server, i seguenti tipi sono i più comuni:

  • Lotto
    • HTTP/HTTPS
    • Prese
  • procedurale (protocollo)
  • In linea
  • Trasmissione

Applicazione di sistemi API

Tutti i servizi e i sistemi online dispongono di API pubbliche. In alcuni casi, devi pagare un abbonamento o un certo numero di accessi per utilizzare l'accesso API. Se il tuo obiettivo è creare un servizio online che fornisca alcune informazioni, presta particolare attenzione all'API. L'approccio e una buona documentazione delle funzionalità dell'API sono la chiave del successo. Tutti gli sviluppatori di terze parti che successivamente creeranno ulteriori applicazioni sono necessari per utilizzare questo protocollo.

Una pratica abbastanza comune è quando il server API è l'unica rappresentazione dei dati dell'intero servizio e la parte client funziona solo attraverso l'applicazione. Vividi esempi di Viber, Instagram, Swarm: queste applicazioni sono anche chiamate Solo mobile (solo su dispositivo mobile). A questo proposito, dovrebbe essere creato un sistema per la distribuzione del carico tra i server API, che consentirà di creare un servizio 24 ore su 24, 7 giorni su 7 con capacità scalabile. Prima di creare la parte server, dovresti valutare immediatamente le possibilità di questo evento e tenere conto di queste opportunità durante lo sviluppo dei programmi.

Per raggiungere la stabilità, gli sviluppi per l'ambiente Linux e il suo servizi di sistema. Ciò è dovuto al fatto che questo sistema operativo è più flessibile, richiede molte risorse e ha alto livello registrazione e debug in caso di arresti anomali. I server Web sono utilizzati come editore o servizi speciali. Abbiamo una serie di sviluppi nei servizi multi-thread per fornire sistemi API.

Abbiamo descritto come funziona, diamo un'occhiata a come fare soldi su di esso? Il primo metodo suggerisce se stesso: la fornitura di servizi tramite l'API. Puoi vendere direttamente servizi o beni: contattando l'API del tuo ristorante formerai un ordine per la consegna a domicilio del cibo. Oppure fornire un servizio utile a pagamento, ad esempio la formazione di rapporti contabili.

Il secondo metodo per guadagnare sull'API è aggregare diversi sistemi in un unico servizio. Abbiamo già discusso del tipo di API per una compagnia aerea, ma ci sono dozzine o addirittura centinaia di compagnie aeree. Ora i servizi di biglietteria sono diventati popolari: Aviasales, OneTwoTrip, Momondo, che in realtà non rappresentano nulla, ma prendono solo API diverse dalle compagnie aeree e pubblicano il proprio servizio che raccoglie dati da queste società. La pratica è molto comune e altamente redditizia.

Il terzo metodo per guadagnare con l'API è il "data mixing". Se torniamo di nuovo alla compagnia aerea, possiamo creare un servizio associato basato su di essa, ad esempio l'assicurazione. Stiamo pubblicando un servizio o un punto di ingresso API alternativo, in cui, oltre ai voli, verranno aggiunte ai dati API le informazioni sull'assicurazione relative a un volo specifico. Così fanno, ad esempio, le compagnie aeree o gli intermediari, espandendo l'API per informare sugli hotel.

Creazione di tecnologie API

Offriamo i nostri servizi per la creazione di server API di tutti i tipi e protocolli descritti in precedenza. Abbiamo esperienza nella creazione di interazioni in vari sistemi ad alto carico. All'uscita, presentiamo non solo un server già pronto (scatola nera), ma anche Descrizione completa protocollo sotto forma di documentazione di progetto. Questa descrizione del protocollo può essere fornita ai seguenti sviluppatori utilizzando questi dati, sia in formato accesso libero per l'opensource.

Oltre al server stesso, possiamo creare un sistema di tracciamento e analisi che segnalerà errori e supererà il carico regolamentato del/dei server.