Maison / Tutoriels Windows / Qu'est-ce que le serveur API. Architecture client-serveur compétente : comment concevoir et développer correctement une API Web. Points de réflexion

Qu'est-ce que le serveur API. Architecture client-serveur compétente : comment concevoir et développer correctement une API Web. Points de réflexion

API Server accepte toutes les requêtes API provenant d'applications externes. Pour authentifier les utilisateurs, API Server utilise un système d'authentification similaire au cryptage à clé publique.

Système cryptographique à clé publique (ou cryptage asymétrique, chiffrement asymétrique) - un système de cryptage et/ou électronique signature numérique(EDS), dans lequel Clé publique transmis sur un canal ouvert (c'est-à-dire non protégé, accessible pour l'observation) et est utilisé pour vérifier la signature numérique et chiffrer le message. Pour générer un EDS et décrypter un message, on l'utilise La clé secrète.

Toutes les requêtes adressées au serveur API sont adressées au fichier du contrôleur frontal. C'est dans ce fichier que sont identifiées les clés publique et privée.

Ici description étape par étape ce processus:

  • Une requête du client API arrive au serveur à l'emplacement du fichier du contrôleur frontal. La requête contient l'APP ID (la clé publique du client) et l'APP KEY (une chaîne de 32 caractères cryptée avec la clé privée du client). La clé secrète n'est jamais envoyée au serveur, elle sert uniquement à chiffrer la requête. La requête contient les paramètres d'appel du serveur : utilisateur, mot de passe d'accès, nom du contrôleur et action qui doit traiter l'appel client. Par exemple, un tableau d'options pourrait ressembler à ceci :
$items = array("controller" => "todo", "action" => "read", "username" => $username, "userpass" => $userpass);
  • Lorsqu'une requête parvient au serveur API, le serveur vérifie dans la liste des applications la présence d'une clé publique (APP ID) ;
  • Si la clé publique n'est pas trouvée, une exception du type "La requête est pas valide". Si la clé est présente, le serveur prend la clé secrète qui correspond à cette clé publique et tente de décrypter la requête entrante ;
  • Si le déchiffrement réussit, les paramètres du contrôleur et de l'action sont extraits de la demande entrante et traités. Le contrôleur frontal qui gère la requête se connecte fichier souhaité contrôleur et invoque l'action contenue dans le paramètre d'action ;
  • En cas de succès/échec du traitement de la demande, le client reçoit une réponse du serveur API.

Vladimir, développeur web Noveo dit

La plupart des développeurs de sites Web, de services Web et d'applications mobiles doivent tôt ou tard faire face à une architecture client-serveur, à savoir développer une API Web ou s'y intégrer. Afin de ne pas inventer quelque chose de nouveau à chaque fois, il est important de développer une approche relativement universelle de la conception d'API Web, basée sur l'expérience de développement de systèmes similaires. Nous attirons votre attention sur une série combinée d'articles sur cette question.

Première approche : les acteurs

À un moment donné, en train de créer le prochain service Web, j'ai décidé de rassembler toutes mes connaissances et réflexions sur le thème de la conception d'une API Web pour répondre aux besoins des applications clientes et de les organiser sous la forme d'un article ou d'un série d'articles. Bien entendu, mon expérience ne prétend pas être absolue, et les critiques et ajouts constructifs sont plus que bienvenus.

La lecture s'est avérée plus philosophique que technique, mais pour les amateurs de la partie technique, il y aura ici de quoi réfléchir. Je doute que je dise quelque chose de fondamentalement nouveau dans cet article, quelque chose que vous n'avez jamais entendu, lu ou pensé sur vous-même. J'essaie juste de tout intégrer système unique, d’abord dans sa propre tête, et cela vaut déjà beaucoup. Néanmoins, je serai heureux si mes fabrications vous seront utiles dans votre pratique. Alors allons-y.

Client et serveur

serveur dans ce cas, nous considérons une machine abstraite sur le réseau capable de recevoir une requête HTTP, de la traiter et de renvoyer une réponse valide. Dans le contexte de cet article, son essence physique et son architecture interne n'ont absolument aucune importance, qu'il s'agisse d'un ordinateur portable d'étudiant ou d'un immense cluster de serveurs industriels dispersés dans le monde. Peu nous importe ce qu'il y a sous le capot, qui répond à la demande à la porte, Apache ou Nginx, quelle bête inconnue, PHP, Python ou Ruby la traite et génère une réponse, quel magasin de données est utilisé : Postgresql , MySQL ou MongoDB . L'essentiel est que le serveur respecte la règle principale : entendre, comprendre et pardonner la réponse.

Client il peut également s'agir de tout ce qui peut former et envoyer une requête HTTP. Jusqu'à un certain point dans cet article, nous ne nous intéresserons pas non plus particulièrement aux objectifs que le client se fixe lors de l'envoi de cette demande, ainsi qu'à ce qu'il fera de la réponse. Le client peut être un script JavaScript exécuté dans le navigateur, application mobile, un démon maléfique (ou pas si) fonctionnant sur le serveur, ou un réfrigérateur trop sage (il y en a déjà).

Pour l’essentiel, nous parlerons de la manière dont les deux ci-dessus communiquent, de manière à ce qu’ils se comprennent, et qu’aucun des deux n’ait de questions.

Philosophie REST

REST (Representational state transfer) a été conçu à l'origine comme une interface simple et sans ambiguïté de gestion de données, impliquant seulement quelques opérations de base avec stockage réseau direct (serveur) : récupération de données (GET), sauvegarde (POST), modification (PUT/PATCH) et suppression (DELETE). Bien entendu, cette liste a toujours été accompagnée d'options telles que la gestion des erreurs dans la demande (la demande est-elle faite correctement), le contrôle d'accès aux données (du coup, vous ne devriez pas le savoir) et la validation des données entrantes (du coup vous avez écrit des bêtises), en général, tout contrôles possibles que le serveur exécute avant de réaliser le souhait client.

De plus, REST comporte un certain nombre de principes architecturaux, dont une liste peut être trouvée dans tout autre article REST. Passons-les brièvement en revue pour qu'ils soient à portée de main et n'aient à aller nulle part :

Indépendance du serveur par rapport au client- les serveurs et les clients peuvent être instantanément remplacés par d'autres indépendamment les uns des autres, puisque l'interface entre eux ne change pas. Le serveur ne stocke pas les états des clients.
Unicité des adresses de ressources- chaque unité de données (quel que soit le degré d'imbrication) a sa propre URL unique, qui, en fait, est entièrement un identifiant unique de la ressource.

Exemple: OBTENIR /api/v1/users/25/nom

Indépendance du format de stockage des données par rapport au format de leur transmission- le serveur peut prendre en charge plusieurs divers formats pour transférer les mêmes données (JSON, XML, etc.), mais stocke les données dans son format interne, quels que soient ceux pris en charge.

Présence de toutes les métadonnées nécessaires dans la réponse- en plus des données elles-mêmes, le serveur doit renvoyer les détails du traitement de la demande, par exemple des messages d'erreur, diverses propriétés de ressources nécessaires à la poursuite des travaux avec, par exemple, le nombre total d'entrées dans la collection pour affichage correct navigation dans les pages. Nous passerons en revue les différents types de ressources.

Que nous manque-t-il

Le REST classique implique le travail du client avec le serveur comme un stockage de données plat, alors que rien n'est dit sur la connectivité et l'interdépendance des données entre elles. Par défaut, tout cela incombe entièrement à l’application cliente. Cependant, les domaines modernes pour lesquels des systèmes de gestion de données sont développés, qu'il s'agisse de services sociaux ou de systèmes de marketing Internet, impliquent une relation complexe entre les entités stockées dans la base de données. Prise en charge de ces liens, c'est-à-dire l'intégrité des données relève de la responsabilité du côté serveur, tandis que le client n'est qu'une interface pour accéder à ces données. Alors, qu’est-ce qui nous manque dans REST ?

Appels de fonction

Afin de ne pas modifier manuellement les données et les liens entre elles, nous appelons simplement une fonction sur la ressource et « nourrissons » les données nécessaires comme argument. Cette opération ne correspond pas aux normes REST, il n'y a pas de verbe spécial pour cela, ce qui nous fait sortir d'un seul coup, nous, les développeurs.

L'exemple le plus simple– autorisation de l'utilisateur. Nous appelons la fonction de connexion, lui transmettons un objet contenant les informations d'identification en argument et recevons une clé d'accès en retour. Ce qui arrive aux données côté serveur ne nous dérange pas.

Une autre option- créer et rompre les liens entre les données. Par exemple, ajouter un utilisateur à un groupe. Faire appel à une entité groupe Fonction addUser, passer l'objet en paramètre utilisateur, on obtient le résultat.

Et aussi il existe des opérations qui ne sont pas directement liées à la sauvegarde des données en tant que telles, par exemple l'envoi de notifications, la confirmation ou le rejet d'éventuelles opérations (fin de la période de reporting, etc.).

Opérations multiples

Cela arrive souvent, et les développeurs clients comprendront ce que je veux dire, qu'il est plus pratique pour une application client de créer/modifier/supprimer/plusieurs objets homogènes à la fois avec une seule requête, et pour chaque objet, un verdict côté serveur est possible. Il y a ici au moins plusieurs options : soit toutes les modifications ont été apportées, soit elles ont été apportées partiellement (pour certains objets), soit une erreur s'est produite. Eh bien, il existe également plusieurs stratégies : appliquer les modifications uniquement en cas de succès pour tout le monde, ou les appliquer partiellement, ou revenir en arrière en cas d'erreur, et cela s'appuie déjà sur un mécanisme de transaction à part entière.

Pour une API Web en quête d'un idéal, j'aimerais également intégrer d'une manière ou d'une autre de telles opérations dans le système. Je vais essayer de le faire dans l'une des suites.

Requêtes statistiques, agrégateurs, formatage des données

Il arrive souvent qu'en fonction des données stockées sur le serveur, nous ayons besoin d'obtenir une compression statistique ou des données formatées d'une manière particulière : par exemple, pour tracer côté client. Essentiellement, il s’agit de données générées à la demande, plus ou moins à la volée, et en lecture seule ; il est donc logique de les classer dans une catégorie distincte. Un des caractéristiques distinctives La statistique, à mon avis, c'est qu'ils n'ont pas de pièce d'identité unique.

Je suis sûr que ce n'est pas tout ce que vous pouvez rencontrer lors du développement d'applications réelles, et je serai heureux de vos ajouts et corrections.

Variétés de données

Objets

Le type de données clé dans la communication entre le client et le serveur est un objet. Essentiellement, un objet est une liste de propriétés et leurs valeurs correspondantes. Nous pouvons envoyer un objet au serveur dans une requête et obtenir le résultat de la requête sous forme d'objet. Dans ce cas, l'objet ne sera pas nécessairement une entité réelle stockée dans la base de données, du moins sous la forme sous laquelle il a été envoyé ou reçu. Par exemple, les informations d'identification pour l'autorisation sont transmises en tant qu'objet, mais ne constituent pas une entité indépendante. Même les objets stockés dans la base de données ont tendance à croître propriétés supplémentaires de nature intra-système, par exemple, les dates de création et d'édition, diverses étiquettes et indicateurs du système. Les propriétés des objets peuvent être soit leurs propres valeurs scalaires, soit contenir objets associés Et collections d'objets, qui ne font pas partie de l'objet. Certaines propriétés des objets peuvent être modifiables, certaines peuvent être en lecture seule, et certaines peuvent être de nature statistique et calculées à la volée (par exemple, le nombre de likes). Certaines propriétés des objets peuvent être masquées, en fonction des droits de l'utilisateur.

Collections d'objets

En parlant de collections, nous entendons une sorte de ressource serveur qui permet de travailler avec une liste d'objets homogènes, c'est-à-dire ajouter, supprimer, modifier des objets et sélectionner parmi eux. De plus, la collection peut théoriquement avoir ses propres propriétés (par exemple, le nombre maximum d'éléments par page) et fonctions (ici je suis confus, mais cela s'est également produit).

Valeurs scalaires

Dans leur forme pure, les valeurs scalaires en tant qu'entité distincte étaient extrêmement rares dans ma mémoire. Ils apparaissent généralement comme propriétés d’objets ou de collections et, en tant que tels, peuvent être lus ou écrits. Par exemple, le nom d'utilisateur peut être récupéré et modifié individuellement avec GET /users/1/name . En pratique, cette fonctionnalité est rarement utile, mais si nécessaire, j'aimerais qu'elle soit à portée de main. Cela est particulièrement vrai pour les propriétés de collection, telles que le nombre d'enregistrements (avec ou sans filtrage) : GET /news/count .

Dans l'un des articles suivants, je vais essayer de classer ces opérations et de proposer des options pour d'éventuelles demandes et réponses, en fonction de celles que j'ai rencontrées dans la pratique.

Deuxième approche : la bonne voie

Dans cette approximation, je voudrais parler séparément des approches permettant de créer des chemins uniques vers les ressources et les méthodes de votre API Web et des fonctionnalités architecturales de l'application qui affectent apparence ce chemin et ses composantes.

À quoi penser quand on est sur la plage

Gestion des versions

Tôt ou tard, tout système d'exploitation commence à évoluer : se développer, devenir plus complexe, évoluer, se moderniser. Pour les développeurs d'API REST, cela se heurte principalement au fait qu'il est nécessaire de lancer de nouvelles versions de l'API pendant que les anciennes fonctionnent. Ici, je ne parle plus des changements architecturaux sous le capot de votre système, mais du fait que le format des données lui-même et l'ensemble des opérations qui les accompagnent changent. Dans tous les cas, le versioning doit être prévu aussi bien dans l’organisation initiale du code source que dans le principe de construction des URL. En ce qui concerne l'URL, il existe deux méthodes les plus courantes pour spécifier la version de l'API à laquelle la requête s'adresse. Préfixe du chemin example-api.com/v1/ et gestion des versions au niveau du sous-domaine v1.example-api.com. Vous pouvez utiliser n'importe lequel d'entre eux, en fonction du besoin et du besoin.

Autonomie des composants

L'API Web des systèmes complexes prenant en charge plusieurs rôles d'utilisateur doit souvent être divisée en parties, chacune servant à un éventail de tâches différent. En fait, chaque partie peut être une application indépendante, fonctionnant sur différentes machines et plates-formes physiques. Dans le contexte de la description de l'API, la manière dont le serveur traite la demande et les forces et technologies impliquées dans cela n'a aucune importance pour nous. Pour le client API, le système est encapsulé. Cependant, différentes parties du système peuvent avoir des fonctionnalités complètement différentes, comme les parties administrative et utilisateur. Et la méthodologie de travail avec les mêmes ressources, semble-t-il, peut différer considérablement. Par conséquent, ces parties doivent être séparées au niveau du domaine admin.v1.example-api.com ou du préfixe de chemin example-api.com/v1/admin/ . Cette exigence n’est pas obligatoire et dépend en grande partie de la complexité du système et de son objectif.

Format d'échange de données

Le format d'échange de données le plus pratique et le plus fonctionnel, à mon avis, est JSON, mais personne n'interdit l'utilisation de XML, YAML ou tout autre format permettant de stocker des objets sérialisés sans perdre le type de données. Si vous le souhaitez, vous pouvez prendre en charge plusieurs formats d'entrée/sortie dans l'API. Il suffit d'utiliser l'entête de requête HTTP pour indiquer le format de réponse souhaité Accept et Content-Type pour indiquer le format des données passées dans la requête. Une autre méthode populaire consiste à ajouter une extension à l'URL de la ressource, telle que GET /users.xml , mais cette méthode semble moins flexible et moins esthétique, ne serait-ce que parce qu'elle alourdit l'URL et est plus vraie pour les requêtes GET que pour toutes. opérations possibles.

Localisation et multilinguisme

En pratique, le multilinguisme des API se réduit le plus souvent à traduire les messages de service et d’erreur dans la langue souhaitée pour un affichage direct à l’utilisateur final. Le contenu multilingue a également sa place, mais la sauvegarde et la diffusion de contenu dans différentes langues, à mon avis, devraient être distinguées plus clairement, par exemple, si vous avez le même article dans différentes langues, alors en fait ce sont deux entités différentes regroupées en signe de l'unité du contenu. Pour identifier la langue attendue, vous pouvez utiliser différentes façons. Le plus simple est l'en-tête HTTP standard Accept-Language . J'ai vu d'autres moyens, comme l'ajout du paramètre GET language="en" , en utilisant le préfixe de chemin example-api.com/en/ , ou même au niveau du nom de domaine en.example-api.com . Il me semble que le choix de la manière de spécifier les paramètres régionaux dépend de l'application spécifique et des tâches auxquelles elle est confrontée.

Routage interne

Nous sommes donc arrivés au nœud racine de notre API (ou de l'un de ses composants). Toutes les autres routes passeront directement dans votre application serveur, conformément à l'ensemble des ressources qu'elle prend en charge.

Chemins de collecte

Pour spécifier le chemin d'accès à la collection, on utilise simplement le nom de l'entité correspondante, par exemple, s'il s'agit d'une liste d'utilisateurs, alors le chemin sera /users . Deux méthodes sont applicables à une collection en tant que telle : GET (obtention d'une liste limitée d'entités) et POST (création d'un nouvel élément). Nous pouvons utiliser de nombreux paramètres GET supplémentaires dans les requêtes d'obtention de listes, utilisés pour la pagination, le tri, le filtrage, la recherche, etc., mais ils doivent être facultatifs, c'est-à-dire ces paramètres ne doivent pas être transmis dans le cadre du chemin !

Éléments de collection

Pour faire référence à un élément spécifique de la collection, nous utilisons son identifiant unique /users/25 dans la route. C’est le chemin unique qui y mène. Pour travailler avec un objet, les méthodes GET (obtention d'un objet), PUT/PATCH (changement) et DELETE (suppression) sont applicables.

Objets uniques

De nombreux services ont des objets uniques à l'utilisateur actuel, tels que le profil /profile de l'utilisateur actuel ou les paramètres personnels /settings . Bien sûr, d'une part, ce sont des éléments d'une des collections, mais ils sont le point de départ de l'utilisation de notre API Web par l'application client, et en plus, ils permettent bien plus large éventail opérations sur les données. Dans le même temps, la collection qui stocke les paramètres utilisateur peut ne pas être disponible du tout pour des raisons de sécurité et de confidentialité des données.

Propriétés des objets et des collections

Pour accéder directement à l'une des propriétés d'un objet, il suffit d'ajouter le nom de la propriété au chemin d'accès à l'objet, par exemple, obtenez le nom d'utilisateur /users/25/name . Les méthodes GET (obtenir la valeur) et PUT/PATCH (changement de valeur) sont applicables à la propriété. La méthode DELETE n'est pas applicable car une propriété est une partie structurelle d’un objet, en tant qu’unité de données formalisée.

Dans la partie précédente, nous avons expliqué comment les collections, comme les objets, peuvent avoir leurs propres propriétés. Dans ma mémoire, seule la propriété count m'a été utile, mais votre application peut être plus complexe et spécifique. Les chemins vers les propriétés des collections sont construits selon le même principe que les propriétés de leurs éléments : /users/count . Pour les propriétés de collection, seule la méthode GET (obtention d'une propriété) est applicable. une collection n'est qu'une interface pour accéder à une liste.

Collections d'objets associés

Un type de propriétés d'objet peut être constitué d'objets associés ou de collections d'objets associés. En règle générale, ces entités ne constituent pas la propriété propre de l'objet, mais seulement des références à ses relations avec d'autres entités. Par exemple, une liste de rôles attribués à l'utilisateur /users/25/roles . Nous parlerons en détail du travail avec des objets et des collections imbriqués dans l'une des parties suivantes, et à ce stade, il nous suffit de pouvoir y accéder directement, comme toute autre propriété d'un objet.

Fonctions d'objet et de collection

Pour construire un chemin vers une interface d’appel de fonction sur une collection ou un objet, nous utilisons la même approche que pour accéder à une propriété. Par exemple, pour l'objet /users/25/sendPasswordReminder ou la collection /users/disableUnconfirmed. Pour les appels de fonction, nous utilisons de toute façon la méthode POST. Pourquoi? Permettez-moi de vous rappeler que dans REST classique, il n'y a pas de verbe spécial pour appeler des fonctions, et nous devrons donc utiliser l'un de ceux existants. À mon avis, la méthode POST est la plus adaptée pour cela. il vous permet de transmettre les arguments nécessaires au serveur, n'est pas idempotent (renvoyant le même résultat en cas d'accès multiple) et est le plus abstrait en termes de sémantique.

J'espère que tout rentre plus ou moins dans le système 🙂 Dans la partie suivante, nous parlerons plus en détail des demandes et réponses, de leurs formats et des codes de statut.

Troisième approche : demandes et réponses

Dans les approximations précédentes, j'ai expliqué comment est née l'idée de collecter et de généraliser l'expérience existante développement web API. Dans la première partie, j'ai essayé de décrire à quels types de ressources et d'opérations nous traitons lors de la conception d'une API Web. La deuxième partie a abordé la problématique de la construction d'URL uniques pour accéder à ces ressources. Et dans cette approximation, je vais essayer de décrire options possibles demandes et réponses.

Réponse universelle

Nous avons déjà dit que le format spécifique de communication entre le serveur et le client peut être quelconque, à la discrétion du développeur. Pour moi, le plus pratique et le plus visuel semble Format JSON, bien qu'une application réelle puisse prendre en charge plusieurs formats. Pour l'instant, concentrons-nous sur la structure et les attributs requis de l'objet de réponse. Oui, nous envelopperons toutes les données renvoyées par le serveur dans un conteneur spécial - objet de réponse générique, qui contiendra toutes les informations de service nécessaires à son traitement ultérieur. Alors quelle est cette information :

Succès - marqueur du succès de la demande

Afin de comprendre immédiatement si la requête a réussi lors de la réception d'une réponse du serveur et de la transmettre au gestionnaire approprié, il suffit d'utiliser le marqueur de réussite « succès ». La réponse du serveur la plus simple, ne contenant aucune donnée, ressemblerait à ceci :

POST /api/v1/articles/22/publish ( "succès": true )

Erreur - informations sur l'erreur

Si la requête échoue - nous parlerons un peu plus tard des raisons et des types de réponses négatives du serveur - l'attribut "erreur" est ajouté à la réponse, contenant le code d'état HTTP et le texte du message d'erreur. Veuillez ne pas confondre avec les messages concernant erreurs de validation données pour des champs spécifiques. Il est plus correct, à mon avis, de renvoyer le code d'état dans l'en-tête de la réponse, mais j'ai également rencontré une autre approche : toujours renvoyer le statut 200 (succès) dans l'en-tête et envoyer les détails et les données d'erreur possibles dans le corps de la réponse.

GET /api/v1/user ( "success": false, "error": ( "code" : 401, "message" : "Échec de l'autorisation") )

Données - données renvoyées par le serveur

La plupart des réponses du serveur sont conçues pour renvoyer des données. Selon le type de requête et son succès, l'ensemble de données attendu sera différent, cependant l'attribut « data » sera présent dans la grande majorité des réponses.

Exemple de données renvoyées en cas de succès. Dans ce cas, la réponse contient l'objet utilisateur demandé.

GET /api/v1/user ( "success": true, "data": ( "id" : 125, "email" : "[email protected]", "name" : "John", "nom" : "Forgeron", ) )

Exemple de données renvoyées en cas d'erreur. Dans ce cas, il contient les noms de champs et les messages d'erreur de validation.

PUT /api/v1/user ( "success": false, "error": ( "code" : 422, "message" : "Validation failed" ) "data": ( "email" : "L'e-mail ne peut pas être vide. ", ) )

Pagination - informations nécessaires pour organiser la pagination

En plus des données réelles, dans les réponses renvoyées ensemble d'éléments de collection, il doit y avoir des informations sur la pagination basées sur les résultats de la requête.

L'ensemble minimum de valeurs pour la pagination comprend :

  • nombre total d'enregistrements ;
  • nombre de pages;
  • numéro de page actuel ;
  • nombre d'enregistrements par page ;
  • le nombre maximum d'enregistrements par page pris en charge par le côté serveur.

Certains développeurs d'API Web incluent également un ensemble de liens prêts à l'emploi vers les pages voisines, ainsi que vers la première, la dernière et la page actuelle dans la pagination.

GET /api/v1/articles Réponse : ( "success": true, "data": [ ( "id" : 1, "title" : "Chose intéressante", ), ( "id" : 2, "title" : "Texte ennuyeux", ) ], "pagination": ( "totalRecords" : 2, "totalPages" : 1, "currentPage" : 1, "perPage" : 20, "maxPerPage" : 100, ) )

Travailler sur les erreurs

Comme mentionné ci-dessus, toutes les requêtes adressées à l’API web n’aboutissent pas, mais cela fait aussi partie du jeu. Le système de rapport d'erreurs est un outil puissant qui facilite le travail du client et guide l'application client sur la bonne voie. Le mot « erreur » dans ce contexte n’est pas tout à fait approprié. Le mot est ici plus approprié. exception, puisqu'en fait la demande a été reçue, analysée avec succès et qu'une réponse adéquate lui est renvoyée, expliquant pourquoi la demande ne peut pas être satisfaite.

Quelles sont les causes potentielles des exceptions que vous obtenez ?

500 Erreur interne du serveur - tout est cassé, mais nous le réparerons bientôt

C'est exactement le cas lorsque le problème s'est produit du côté du serveur lui-même, et que l'application client ne peut que soupirer et informer l'utilisateur que le serveur est fatigué et se repose. Par exemple, la connexion à la base de données est perdue ou il y a un bug dans le code.

400 Mauvaise requête - et maintenant tout est cassé

La réponse est exactement le contraire de la précédente. Renvoyé lorsque l'application client envoie une requête qui, en principe, ne peut pas être traitée correctement, ne contient pas les paramètres requis ou comporte des erreurs de syntaxe. Ce problème est généralement résolu en relisant la documentation de l'API Web.

401 Non autorisé - étranger, identifiez-vous

Une autorisation est requise pour accéder à cette ressource. Bien entendu, la présence d'une autorisation ne garantit pas que la ressource deviendra disponible, mais sans autorisation, vous ne le saurez pas avec certitude. Se produit par exemple lors d'une tentative d'accès à la partie privée de l'API ou lorsque le token actuel expire.

403 Interdit - vous ne pouvez pas venir ici

La ressource demandée existe, mais l'utilisateur ne dispose pas des droits suffisants pour la visualiser ou la modifier.

404 Non trouvé - personne n'habite à cette adresse

Une telle réponse est renvoyée, en règle générale, dans trois cas : le chemin d'accès à la ressource est incorrect (erroné), la ressource demandée a été supprimée et a cessé d'exister, les droits de l'utilisateur actuel ne lui permettent pas de connaître l'existence de la ressource demandée. Par exemple, en parcourant une liste de produits, l’un d’entre eux est soudainement passé de mode et a été supprimé.

405 Méthode non autorisée

Ce type d'exception est directement lié au verbe utilisé dans la requête (GET, PUT, POST, DELETE), qui, à son tour, indique l'action que nous essayons d'effectuer avec la ressource. Si la ressource demandée ne prend pas en charge l'action spécifiée, le serveur l'indique directement.

422 Entité non traitable - corriger et renvoyer

Une des exceptions les plus utiles. Renvoyé chaque fois qu'il y a des erreurs logiques dans les données de la demande. Par données de requête, nous entendons soit un ensemble de paramètres et leurs valeurs correspondantes transmises par la méthode GET, soit les champs d'un objet transmis dans le corps de la requête par les méthodes POST, PUT et DELETE. Si les données ne sont pas validées, le serveur dans la section « données » renvoie un rapport indiquant quels paramètres ne sont pas valides et pourquoi.

Le protocole HTTP prend en charge beaucoup plus divers codes de statut pour toutes les occasions, mais dans la pratique, ils sont rarement utilisés et dans le contexte de l'API Web ne sont d'aucune utilité pratique. Dans ma mémoire, je n’ai pas eu à aller au-delà de la liste d’exceptions ci-dessus.

Demandes

Récupérer les éléments d'une collection

L’une des requêtes les plus fréquentes est celle visant à récupérer les éléments d’une collection. Des flux d'informations, des listes de produits, diverses informations et tableaux statistiques, et bien plus encore, sont affichés par l'application client en accédant aux ressources de collecte. Pour faire cette requête, nous accédons à la collection en utilisant la méthode GET et en passant des paramètres supplémentaires dans la chaîne de requête. Comme nous l'avons déjà indiqué plus haut, en réponse, nous attendons de recevoir un tableau d'éléments homogènes de la collection et les informations nécessaires à la pagination - chargement de la suite de la liste ou de sa page spécifique. Le contenu de la sélection peut être limité de manière particulière et trié en passant options additionelles. Ils seront discutés plus loin.

Pagination

page- le paramètre indique quelle page doit être affichée. Si ce paramètre n'est pas passé, alors la première page s'affiche. Dès la première réponse réussie du serveur, il sera clair combien de pages contient la collection avec les paramètres de filtrage actuels. Si la valeur dépasse le nombre maximum de pages, il est alors plus raisonnable de renvoyer une erreur. 404 Non trouvé.

OBTENIR /api/v1/news?page=1

par page- indique le nombre d'éléments souhaité par page. Généralement, l'API a sa propre valeur par défaut qui renvoie le champ perPage dans la section de pagination, mais dans certains cas, elle vous permet d'augmenter cette valeur jusqu'à des limites raisonnables en fournissant une valeur maxPerPage maximale :

OBTENIR /api/v1/news?perPage=100

Trier les résultats

Souvent, les résultats d'une sélection doivent être triés par ordre croissant ou décroissant selon les valeurs de certains champs prenant en charge le tri comparatif (pour les champs numériques) ou alphabétique (pour les champs de chaîne). Par exemple, nous devons trier la liste des utilisateurs par nom ou des produits par prix. De plus, nous pouvons définir le sens de tri de A vers Z ou dans le sens opposé, et différent selon les champs.

Trier par- Il existe plusieurs approches pour transmettre des données sur le tri complexe dans les paramètres GET. Ici, vous devez spécifier clairement l'ordre et la direction du tri.

Certaines API suggèrent de le faire sous forme de chaîne :

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

D'autres options suggèrent d'utiliser un tableau :

OBTENIR /api/v1/products ? sortBy=nom& sortBy=desc& sortBy=prix& sortBy=asc

En général, les deux options sont équivalentes, puisqu’elles transmettent les mêmes instructions. A mon avis, l'option avec un tableau est plus polyvalente, mais ici, comme on dit, le goût et la couleur...

Filtrage simple par valeur

Afin de filtrer la sélection par la valeur d'un champ, il suffit dans la plupart des cas de transmettre le nom du champ et la valeur souhaitée comme paramètre de filtrage. Par exemple, nous souhaitons filtrer les articles par identifiant d'auteur :

OBTENIR /api/v1/articles?authorId=25

Options de filtrage sophistiquées

De nombreuses interfaces nécessitent des systèmes de filtrage et de recherche plus complexes. Je vais énumérer les options de filtrage principales et les plus courantes.

Filtrage par limites supérieure et inférieure à l'aide d'opérateurs de comparaison de (supérieur ou égal à), supérieur (supérieur à), à (inférieur ou égal à), inférieur (inférieur à). S'applique aux champs dont les valeurs sont classables.

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

Filtrage par plusieurs valeurs possibles de la liste. Appliqué aux champs, défini valeurs possibles qui se limite, par exemple, à un filtre par plusieurs statuts :

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

Filtrage par correspondance de chaîne partielle. S'applique aux champs contenant des données textuelles ou des données pouvant être traitées comme du texte, telles que des numéros de produit, des numéros de téléphone, etc.

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

Filtres nommés

Dans certains cas, lorsque certains ensembles de paramètres de filtrage sont souvent utilisés et sont compris par le système comme quelque chose d'intégral, surtout s'ils affectent la mécanique interne, souvent complexe, de l'échantillonnage, il est conseillé de les regrouper dans ce que l'on appelle des filtres nommés. Il suffit de transmettre le nom du filtre dans la requête, et le système construira automatiquement la sélection.

GET /api/v1/products?filters=recommandé

Les filtres nommés peuvent également avoir leurs propres paramètres.

OBTENIR /api/v1/products?filters=kidds

Dans cette sous-section, j'ai essayé de parler des options et des moyens les plus populaires d'obtenir l'échantillon requis. Très probablement, dans votre pratique, il y aura beaucoup plus d'exemples et de nuances concernant ce sujet. Si vous avez quelque chose à ajouter à mon matériel, j'en serai qu'avec plaisir. Entre-temps, le poste a déjà atteint une taille solide, nous analyserons donc d'autres types de demandes dans un proche avenir.

6.1 Méthode CheckDimensions

Syntaxe:

Booléen Vérifier les dimensions(Dimensions DimensionsListe,

Longueur à flot,

Largeur de déversement,

Hauteur de déversement,

Poids à flot,

Commentaire de chaîne)

Possibilités :

Le nom du paramètre Entrée sortie Taper Description
Liste des dimensions saisir Dimensions tableau
poids total
caractéristiques du produit
Longueur jour de congé flotter Longueur du colis
Largeur jour de congé flotter Largeur de la parcelle
Hauteur jour de congé flotter Hauteur du colis
Poids jour de congé flotter Poids du colis
Commentaire jour de congé flotter Description textuelle en cas de dépassement
valeurs limites du poids total
caractéristiques

Description:

La liste des caractéristiques de poids et de taille de toutes les marchandises est transmise à la méthode
(Liste des dimensions). Après calcul, les paramètres de sortie Longueur, Largeur, Hauteur (longueur,
largeur et hauteur, respectivement) sont renseignés avec les dimensions de la parcelle, après résolution
problème de "empilement optimal", et le paramètre Poids est transmis au poids total de tous
marchandises, à l’exclusion des matériaux d’emballage. Dans le cas où les dimensions de l'envoi
dépassent les valeurs limites, une description textuelle est transmise au paramètre Commentaire
incohérences.

Valeur de retour : La méthode renvoie un booléen True si
les caractéristiques de poids globales ne dépassent pas les valeurs limites et la livraison
possible au moins un voie accessible, sinon Faux. Vraisemblablement donné
la méthode peut être utilisée côté client pour une évaluation en ligne
la possibilité fondamentale d'envoyer une commande et l'acceptation en temps opportun de tout
décisions si cela n’est pas possible.

6.1.1 Un exemple d'appel de la méthode CheckDimensions



// Supposons qu'il y ait 2 positions dans le panier et que vous deviez vérifier si elle dépasse
restrictions sur les dimensions et le poids autorisés
aplix.Dimensions Dimensions = nouveau aplix.Dimensions;
aplix.DimensionsItem;

Article.Longueur = 0,130f ;
Article.Largeur = 0,100f ;
Article.Hauteur = 0,001f ;
Article.Poids = 0,1f ;
Article.Qté = 2 ;
Dimensions = article ;
Article = new aplix.Dimensions();
Article.Longueur = 0,1331f ;
Article.Largeur = 0,0998f ;
Article.Hauteur = 0,0788f ;
Article.Poids = 0,575f ;
Article.Qté = 1 ;
Dimensions = article ;
// Paramètres de sortie
Longueur du flotteur ;
largeur flottante ;
Hauteur du flotteur ;
poids du flotteur ;
chaîne Commentaire ;
// Effectuer une vérification du poids
bool Result = ws.CheckDimenshions(Dimensions, longueur extérieure, largeur extérieure, hauteur extérieure, poids extérieur, commentaire extérieur) ;
// Visualisation du résultat
Réponse.Write("Résultat : " + Résultat.ToString() + "");
Réponse.Write("Longueur : " + Longueur.ToString() + "");
Réponse.Write("Largeur : " + Largeur.ToString() + "");
Response.Write("Hauteur : " + Hauteur.ToString() + "");
Response.Write("Poids : " + Weight.ToString() + "");
Response.Write("Poids : "+Commentaire+"");

6.2 Méthode CalculateShippingCost

Syntaxe:
Long Calculer les frais d'expédition(chaîne Numéro de commande,
coût déclaré flottant,
Marchandises Marchandises,
Adresse,
Type d'octet de sceau,
Emballage robuste booléen,
CashOnDelivery booléen,
Types de types de livraison,
Commentaires sur la chaîne de sortie)Paramètres :

Le nom du paramètre Entrée sortie Taper Description
Numéro de commande saisir chaîne Numéro de commande, s'il est connu dans le système
consommateur. Si cela est donné, alors le calcul
à l'avenir sera lié à la commande.
coût déclaré saisir flotter La valeur déclarée de l'envoi. Sur

assurance.
Marchandises saisir Marchandises Liste des biens gamme de structures
(Code de fournisseur,
Nom,
Longueur,
Largeur, Hauteur, Poids, Quantité)
adresse saisir adresse Adresse du destinataire (structure : Postale
indice,
Région,
Zone,
Ville,
Localité, Rue, Maison, Logement,
Kartira)
Type de joint saisir octets Option
scellés,
possible
valeurs : 1 Non requis

2 papiers bulles

3 Remplisseur

Emballage robuste saisir Booléen Est-il nécessaire d'avoir un rigide
emballer
Paiement à la livraison saisir Booléen Le paiement à la livraison est-il requis
les types jour de congé Type de livraison
commentaires jour de congé Type de livraison Liste des options d'expédition disponibles

Description:

Méthode par paramètres donnés affiche une liste des options de livraison disponibles
(Types de paramètres de sortie) sous forme de tableau de structures<Идентификатор способа доставки, Наименование способа доставки, Себестоимость доставки, Страховую премию, Затраты на упаковку и маркировку, Адрес нахождения почтового отделения, либо точки самовывоза, Режим работы почтового отделения, либо точки самовывоза, Минимальное количество дней доставки, Максимальное количество дней доставки, Доп.информация>. S'il y a des exceptions lors du calcul, alors
une description de l'erreur sera renvoyée dans le paramètre Commentaires.

Valeur de retour :

La méthode renvoie un identifiant unique du calcul, selon lequel à l'avenir
il sera possible de demander le détail des coûts de matériel et de main d'œuvre selon la méthode
GetDetailsOfCost.

6.2.1 Un exemple d'appel de la méthode CalculateShippingCost



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


Adresse.Index = "684005" ;


Adresse.City = "Ville d'Elizovo";

Adresse.Accueil = "16" ;


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

Article.Longueur = 0,130f ;
Article.Largeur = 0,100f ;
Article.Hauteur = 0,001f ;
Article.Poids = 0,1f ;
Article.Qté = 2 ;
Marchandises = article ;
Article = new aplix.Goods();
Article.SKU = "499687" ;

Article.Longueur = 0,1331f ;
Article.Largeur = 0,0998f ;
Article.Hauteur = 0,0788f ;
Article.Poids = 0,575f ;
Article.Qté = 1 ;
Marchandises = article ;
//Remplissez les paramètres de la calculatrice
stringOrderNumber="1234567890";
float Coût déclaré = 36370 ;
octet TypeOfSeal = 1 ;
bool SturdyPackaging = true ;
bool CashOnDelivery = faux ;
Types aplix.DeliveryType ; chaîne Commentaires ;
//appel de la calculatrice
long Status = ws.CalculateShippingCost (OrderNumber, DeclaredCost, Goods, Address, TypeOfSeal, SturdyPackaging, CashOnDelivery, types de sortie, commentaires de sortie) ;
//Visualisation des résultats
Response.Write("ID de calcul : "+Status.ToString()+"
");
Response.Write("Informations supplémentaires sur le calcul : " + Commentaires + "
");
Réponse.Écrire (@"
");
foreach (type aplix.DeliveryType dans Types) (
Response.Write(""+ " "+ " "+ " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " "); )
Réponse.Write("
































ID de type TypeName TypeDescription coût Assurance Tarif postal coût de préparation adresse Temps de travail Période Min Période Max Informations Complémentaires
" + type.TypeId.ToString() + " " + type.TypeName + " " + type.TypeDescription + " " + type.Cost.ToString() + " " + type.Insurance.ToString() + " " + type.PostalRate.ToString() + " " + type.PreparingCost.ToString() + " " + tapez.Adresse + " " + tapez.Temps de travail + " " + type.MinPeriod.ToString() + " " + type.MaxPeriod.ToString() + " " + tapez.Informations supplémentaires + "

");
}

6.3 Méthode PushOrder

Syntaxe:
Long commande push(
identifiant,
nombre,
date,
client,
coût déclaré,
Montant à payer,
ID de type de livraison,
Type de joint,
Emballage robuste,
activité,
marchandises,
la date de livraison,
Heure de débutLivraison,
Heure de fin de livraison,
commentaire,
expédition,
marqueur)
Possibilités :

Le nom du paramètre Entrée sortie Taper Description
IDENTIFIANT saisir Chaîne ID de commande dans le système
consommateur ( valeur unique)
nombre saisir Chaîne Numéro de commande dans le système du client
(sera imprimé dans les commentaires)
lors du marquage des envois)
Date saisir dateheure La date de la commande dans le système du consommateur (sera
imprimer dans les commentaires
marquage des expéditions
client saisir client Informations sur l'acheteur, structure
coût déclaré saisir flotter La valeur déclarée de l'envoi. Sur
le montant indiqué sera émis
assurance.
MontantVersP
aide
saisir flotter Somme
À
paiement.
Si
commande
prépayer puis 0.
ID de type de livraison saisir int ID de la méthode sélectionnée
livraison.
Type de joint saisir int Option
scellés,
possible
valeurs:
1Non requis
2 papiers bulles
3Remplisseur
Emballage robuste saisir Booléen Est-il nécessaire d'avoir un rigide
emballer
Activité saisir Booléen Pertinence de la commande. Vrai - si la commande
valide, Faux – si la commande est annulée.
Marchandises saisir Marchandises Liste de produits
La date de livraison saisir dateheure Date de livraison, renseignée si sélectionnée
livraison express
HeureDébutDeliv
très
saisir int Liste de souhaits
temps
livraison
"AVEC",

livraison
Heure de finLivraison saisir int Délai de livraison souhaité "À",
à remplir si le transporteur est sélectionné
livraison
Commentaire saisir Chaîne Commentaire sur la commande
ID de l'expéditeur saisir Chaîne Identifiant
expéditeur,
est rempli
Si
chez la contrepartie
plusieurs boutiques en ligne
marqueur saisir Chaîne Marqueur de commande, rempli si
les envois sont étiquetés
site web

Description:
Le procédé place des informations sur la commande dans le système de l'entrepreneur. consommateur du système
transmet le numéro et la date de la commande, un identifiant unique de commande, des informations sur
le destinataire, comprenant son adresse et son numéro de téléphone, la valeur déclarée, le montant de la taxe imposée
paiement, le cas échéant, la composition de la marchandise attachée, le type d'emballage et le choix
mode de livraison et détails.

Valeur de retour :
La méthode renvoie un identifiant de commande unique dans le système de l'entrepreneur.

6.3.1 Exemple d'appel de la méthode PushOrder


aplix.Delivery ws = new aplix.Delivery();
ws.Credentials = new NetworkCredential("test", "test");
// Préparer la structure "Envoyer le destinataire"
aplix.Customer = new aplix.Customer();
// 684005, Kraï du Kamtchatka, quartier Elizovsky, ville d'Elizovo, rue Leninskaya, maison n°16
aplix.Address Adresse = new aplix.Address();
Adresse.Index = "684005" ;
Adresse.Région = « Kraï du Kamtchatski » ;
Adresse.District = "Quartier Elizovsky" ;
Adresse.City = "Ville d'Elizovo";
Adresse.Street = « Rue Leninskaya » ;
Adresse.Accueil = "16" ;
Customer.Address = Adresse ;
Client.ID = " [email protégé]";
Client.Nom = "Sergey" ;
Client.Email = " [email protégé]";
Client.Téléphone = "+7(916)975-53-54" ;
//Remplissez les paramètres de la commande
ID de chaîne = "2013-1234567890" ; // Identifiant unique de la commande dans le système du client
numéro de chaîne = "1234567890" ; // Numéro de commande dans le système du client
DateHeure Date = nouveau DateHeure (2013, 08, 30);
float DeclaredCost = 36350.0f; // Valeur déclarée
float MontantToBePaid = 0 ; // Pas de paiement à la livraison
int DeliveryTypeId = 4 ; // CEM
octet TypeOfSeal = 2 ; // Papier bulle
bool SturdyPackaging = true ; // Emballage rigide (pour objets fragiles)
bool Activité = vrai ; // Le document est à jour
// Supposons que la commande se compose de 2 articles
aplix.Goods Goods = nouveau aplix.Goods;
aplix.GoodsItem;
Article = new aplix.Goods();
Article.SKU = "216293" ;
Item.Name = "SDXC 64 Go classe 10 Transcend" ;
Article.Longueur = 0,130f ;
Article.Largeur = 0,100f ;
Article.Hauteur = 0,001f ;
Article.Poids = 0,1f ;
Article.Qté = 1 ;
Article.Prix = 2080.0f ;
Article.VATRate = "TVA18" ;
Marchandises = article ;
Article = new aplix.Goods();
Article.SKU = "499687" ;
Item.Name = « Kit Canon EOS 650D Tamron AF 18-270 mm noir » ;
Article.Longueur = 0,1331f ;
Article.Largeur = 0,0998f ;
Article.Hauteur = 0,0788f ;
Article.Poids = 0,575f ;
Article.Qté = 1 ;
Article.Prix = 34270.0f ;
Article.VATRate = "TVA18" ;
Marchandises = article ;
DateTime DeliveryDate = new DateTime (2013, 09, 05); //Livraison le 05 09 2013
int StartTimeDelivery = 10 ; // intervalle de livraison à partir de 10
int EndTimeDelivery = 14 ; // jusqu'à 14
string Comment = "Ordre de test" ;
//Introduisez la commande dans le système
long OrderId = ws.PushOrder(ID, Number, Date, Customer, DeclaredCost, AmountToBePaid,DeliveryTypeId, TypeOfSeal, SturdyPackaging, Activity, Goods, DeliveryDate, StartTimeDelivery,EndTimeDelivery, Comment, "", "");
Response.Write("ID de commande : " + OrderId.ToString() + "
");

6.4 Méthode GetDetailsOfCost

Syntaxe :        DetailsOfCostList GetDetailsOfCost (ID, TypeId) Paramètres :

Entrée sortie
Taper
Description

saisir
Long
ID de calcul (valeur unique) obtenu en appelant la méthode CalculateShippingCost

saisir
int

Le nom du paramètre
IDENTIFIANT ID de type

Description : la méthode renvoie une liste détaillée des coûts d'étiquetage et d'emballage d'un envoi pour l'ID de facturation et l'ID d'option de livraison spécifiés. Valeur de retour : La méthode renvoie un tableau de structures

Chaque élément du tableau contient une description du coût, de la quantité, du prix et du coût.

6.4.1 Exemple d'appel de la méthode GetDetailsOfCost


aplix.Delivery ws = new aplix.Delivery();
ws.Credentials = new NetworkCredential("test", "test");
ID long = 168 ; // ID de calcul reçu par la méthode CalculateShippingCost
int TypeId = 3 ; // Livraison postale

aplix.DetailsOfCost Détails = ws.GetDetailsOfCost(ID, TypeId);
//Visualisation des résultats
Response.Write("ID de calcul : " + ID.ToString() + "
");
Response.Write("Identifiant du mode de livraison : " + TypeId.ToString() + "
");
Réponse.Écrire (@"


");
foreach (aplix.DetailsOfCost DetailOfCost dans les détails)
{
Réponse.Write("" + " " + " " + " " + " " + " ");
}
Réponse.Write("















Description prix Quantité coût
" + DétailOfCost.Description + " " + DetailOfCost.Price.ToString() + " " + DétailOfCost.Qty.ToString() + " " + DétailOfCost.Cost.ToString() + "

");

6.5 Méthode PushReestr

Syntaxe : Long PushOrder (ID, Numéro, Date, DateOfShipment, ID) Paramètres :

Entrée sortie
Taper
Description

saisir
Chaîne
ID de registre sur le système consommateur (valeur unique)

saisir
Chaîne
Identifiant du mode de livraison pour lequel vous souhaitez obtenir le détail

saisir
dateheure
Date d'enregistrement (sera imprimée sur les certificats d'acceptation des expéditions)

saisir
dateheure
Date prévue de transfert des articles à l'entrepreneur

saisir
Chaîne
Un tableau d'ID de commande inclus dans ce registre

Le nom du paramètre
IDENTIFIANT nombre Date Date d'expédition identifiants

Description : La méthode place des informations sur le registre dans le système de l'exécuteur. Le consommateur du système transmet le numéro et la date du registre, l'identifiant unique du registre, la date prévue de transfert des pièces à l'exécuteur testamentaire. Valeur de retour : La méthode renvoie un identifiant unique du registre dans le système de l'exécuteur.

6.5.1 Exemple d'appel de la méthode PushReestr


aplix.Delivery ws = new aplix.Delivery();
ws.Credentials = new NetworkCredential("test", "test");
// Liste des identifiants de commande inclus dans ce registre
ID de chaîne = ("2013-1234567890", "2013-1234567891");
// Identifiant unique du registre dans le système client
ID de chaîne = "2013-r12345" ;
// Numéro de registre dans le système client
numéro de chaîne = "r12345" ;
// Date de constitution du registre dans le système du client
DateHeure Date = nouveau DateHeure (2013, 10, 22);
// Date estimée de transfert des commandes pour livraison
DateTime DateOfShipment = new DateTime (2013, 10, 23);
// Récupère les détails du calcul
long ReestID = ws.PushReestr (ID, numéro, date, date d'expédition, identifiants);
//Visualisation des résultats
Response.Write("ID de registre : " + ReestID.ToString() + "
");

6.6 Méthode GetTrackNumbers

Syntaxe : dateheure Obtenir les numéros de piste(DateOfLastGetting, TrackNumbers) Paramètres :

Entrée sortie
Taper
Description

saisir
dateheure
Date de la dernière réception réussie des numéros de piste. Le paramètre est utilisé pour réduire la quantité de données transférées et ne pas dupliquer les données téléchargées précédemment.

saisir
numéro de piste
Tableau de numéros de piste pour les commandes

Le nom du paramètre
Date du dernier obtention Numéros de piste

Description : la méthode renvoie une liste de numéros de piste associés aux commandes pour la période allant de DateOfLastGetting à heure actuelle. Le résultat est placé dans le paramètre de sortie TrackNumbers. La propriété Activity est définie sur true si le numéro de piste est à jour, false sinon. Il existe des situations où un envoi se voit attribuer un numéro de piste, et après un deuxième numéro de piste, dans ce cas, le numéro de piste attribué initialement n'a plus d'importance. Valeur de retour : La méthode renvoie la date et l'heure pour lesquelles les données téléchargées sont pertinentes. Valeur donnée doit être utilisé la prochaine fois que la méthode GetTrackNumbers est appelée dans le paramètre DateOfLastGetting.

6.6.1 Exemple d'appel de la méthode GetTrackNumbers


aplix.Delivery ws = new aplix.Delivery();
ws.Credentials = new NetworkCredential("test", "test");
// Date de la dernière réception réussie des titres
DateTime DateOfLastGetting = new DateTime (2013, 08, 01);
aplix.TrackNumber TrackNumbers;
// Obtenez une liste de numéros de piste
DateTime NewDateOfLastGetting = ws.GetTrackNumbers(DateOfLastGetting, sur TrackNumbers);
//Visualisation des résultats
Réponse.Write("NewDateOfLastGetting : " + NewDateOfLastGetting.ToString() +"
");
Réponse.Écrire (@"


");
foreach (aplix.TrackNumber TrackNumber dans TrackNumbers)
{
Réponse.Write("" + " " + " " + " " + " ");
}
Réponse.Write("













Numéro de commande numéro de piste Activité
" + TrackNumber.OrderID.ToString() + " " + TrackNumber.Number + " "+TrackNumber.Activité+"

");

L'API (Application Programming Interface) est certaine représentation données pour l’interaction entre les applications. Dans un cas particulier, le serveur peut faire office d'application de réponse. L'API est un format décrit auquel les deux parties de l'échange de données doivent se conformer.

La technologie des différentes API est un ensemble de méthodes d'interaction. Le système API sous une forme ou une autre est présenté partout. Par exemple, nous avons entre les mains un smartphone avec une application d’achat de billets. Au niveau "le plus élevé", on voit la partie graphique de l'application avec les champs de saisie des données. Nous demandons des vols le long de l'itinéraire pour un jour spécifique et ce qui se passe à ce moment-là :

  1. L'application mobile génère une requête au serveur. La demande est formée dans un certain format. Par exemple : Départ : Moscou DME, Arrivée : AmsterdamAMS, Date : 01-01-2017, Sièges : 2, Classe : Économie. Cette ligne contient un format strict - Titre : Valeur, toutes les valeurs séparées par des virgules, les champs obligatoires Départ, Arrivée et Date, si aucune autre donnée n'est précisée, elles seront par défaut : Sièges : 1, Classe : Économique.
  2. Le serveur de la compagnie aérienne reçoit cette demande et le programme comprend qu'il est nécessaire de trouver des vols et des prix.
  3. Le serveur accède à la base de données en SQL, qui est également une représentation privée de l'API
  4. La base de données accède au fichier via l'API du système de fichiers
  5. Le système de fichiers accède au disque dur via son protocole API.

Vous pouvez continuer à approfondir, mais il est clair que toute tâche de programmation construit une hiérarchie d’API.

Aujourd’hui, sous une forme ou une autre, toutes les informations sous forme informatique sont représentées par API.

Nous développons des systèmes API pour la couche supérieure, où le prochain consommateur est l'application client.

Classification des types d'API

Selon la tâche à résoudre, les protocoles de transfert d'API peuvent être à la fois standardisés et avoir leur propre format. Protocoles standardisés les plus couramment utilisés, ils permettent aux développeurs d'utiliser des modules prêts à l'emploi pour leur traitement, ce qui réduit le temps de développement d'une application. Différents types spécifiques sont utilisés pour obtenir certains avantages, tels qu'une réduction du trafic, une rapidité de reconnaissance des commandes et, dans certains cas - c'est la seule possibilité - le développement de votre propre format - par exemple, la diffusion de vidéo avec une composante éphéméride.

Selon le type d'informations transmises, l'API est divisée selon les formats suivants :

  • Protocoles API standards
    • Texte
  • Binaire
    • en ligne
    • personnel

Selon le type d'interaction client-serveur, les types suivants sont les plus courants :

  • Lot
    • HTTP/HTTPS
    • Prises
  • procédural (protocole)
  • En ligne
  • Diffuser

Application des systèmes API

Tous les services et systèmes en ligne disposent d’API publiques. Dans certains cas, vous devez payer un abonnement ou un certain nombre de visites pour pouvoir utiliser l'accès API. Si votre objectif est de créer un service en ligne fournissant des informations, portez une attention particulière à l'API. Une approche et une bonne documentation des fonctionnalités de l'API sont la clé du succès. Tous les développeurs tiers qui créeront par la suite applications supplémentaires sont nécessaires pour utiliser ce protocole.

Une pratique assez courante est lorsque le serveur API est la seule représentation des données de l'ensemble du service et que la partie client ne fonctionne que via l'application. Exemples frappants de Viber, Instagram, Swarm - ces applications sont également appelées Mobile uniquement (uniquement sur mobile). À cet égard, un système de répartition de la charge entre les serveurs API devrait être créé, ce qui permettra de créer un service 24h/24 et 7j/7 avec une capacité évolutive. Avant de créer la partie serveur, vous devez immédiatement évaluer les possibilités de cet événement et prendre en compte ces opportunités lors du développement de programmes.

Pour parvenir à la stabilité, les développements pour l'environnement Linux et ses services système. Cela est dû au fait que cela système opérateur plus flexible, gourmand en ressources et a haut niveau journalisation et débogage en cas de crash. Les serveurs Web sont utilisés comme éditeur ou services spéciaux. Nous avons un certain nombre de développements dans les services multithread pour fournir des systèmes API.

Nous avons décrit comment cela fonctionne, voyons comment gagner de l'argent avec cela ? La première méthode s'impose d'elle-même : la fourniture de services via l'API. Vous pouvez vendre des services ou des biens directement - contacter l'API de votre restaurant formera une commande de livraison de nourriture à domicile. Ou fournir service utile sur une base rémunérée, par exemple, la constitution de rapports comptables.

La deuxième méthode pour gagner de l'argent sur l'API consiste à regrouper plusieurs systèmes en un seul service. Nous avons déjà évoqué le type d’API pour une compagnie aérienne, mais il existe des dizaines, voire des centaines de compagnies aériennes. Aujourd'hui, les services de billetterie sont devenus populaires - Aviasales, OneTwoTrip, Momondo, qui ne représentent rien en réalité, mais prennent uniquement différentes API des compagnies aériennes et publient leur propre service qui collecte les données de ces sociétés. La pratique est très courante et très rentable.

La troisième méthode pour gagner de l'argent avec l'API est le « mélange de données ». Si nous revenons à la compagnie aérienne, nous pouvons alors créer un service associé basé sur elle, par exemple une assurance. Nous publions un service ou un point d'entrée API alternatif, où, en plus des vols, des informations sur l'assurance liée à un vol spécifique seront ajoutées aux données API. C'est le cas, par exemple, des compagnies aériennes ou des intermédiaires, qui étendent l'API pour informer sur les hôtels.

Création de technologies API

Nous proposons nos services pour créer des serveurs API de tous types et protocoles décrits précédemment. Nous avons de l'expérience dans la création d'interactions dans divers systèmes très chargés. En sortie, nous présentons non seulement un serveur prêt à l'emploi (boîte noire), mais aussi Description complète protocole sous forme de documentation de conception. Cette description du protocole peut être fournie aux développeurs suivants utilisant ces données, soit dans accès libre pour l'open source.

En plus du serveur lui-même, nous pouvons créer un système de suivi et d'analyse qui signalera les erreurs et dépassera la charge réglementée du ou des serveurs.