Essayons d'écrire une petite formation, mais un système d'information assez complet composé d'une partie serveur sur Go et d'une application web client sur Javascript + Vue JS.
Tout d'abord, quelques mots sur ce qu'est cette application et à quoi elle sert. Il y a quelque temps, la question s'est posée devant moi de savoir comment économiser une certaine somme d'argent que j'avais formée. Même pour moi, une personne loin du monde de la finance, il était évident que détenir de l'argent en espèces était mauvais pour au moins deux raisons:
- L'argent ronge l'inflation (risque inflationniste)
- Le rouble peut se déprécier (risque de change)
Il a été décidé d'étudier la question et de choisir l'outil d'investissement approprié. Les principaux critères étaient la fiabilité et la protection de l'épargne contre les risques ci-dessus.
J'ai étudié la question et, par conséquent, je suis arrivé à la conclusion que le seul outil d'investissement adéquat pour un Russe est les fonds négociés en bourse (ETF) et ceux qui sont négociés à la Bourse de Moscou.
Ainsi, je propose d'écrire une application de formation qui montrerait la rentabilité de tous les ETF présentés à la Bourse de Moscou.
Vous pouvez dire que cette rentabilité peut être consultée sur le site Web d'échange lui-même, et l'application, au moins pour la formation, devrait être quelque peu utile. Je suis d'accord, par conséquent, nous essaierons d'afficher un rendement réel conditionnel des actions. Par ce rendement réel conditionnel, je veux dire le taux de rendement ajusté pour l'inflation en Russie.
Dans la première partie de l'article, nous analyserons la partie serveur de l'application. Notre backend est écrit en Go et pendant le développement, nous essaierons d'appliquer des fonctionnalités du langage telles que l'exécution de code parallèle, les interfaces, les tests et plus encore.
Exigences en matière de savoirs traditionnels:
- La partie serveur de l'application doit fournir, sur demande, des données sur les cotations de tous les ETF de la Bourse de Moscou et des données d'inflation pour tous les mois de négociation pour chaque papier.
- La partie serveur de l'application doit prendre en charge plusieurs fournisseurs d'entrepôt de données, le basculement entre les fournisseurs ne devrait pas nécessiter de modifications de code
- La partie serveur de l'application doit fournir l'API via le protocole http pour recevoir les données du stockage
Concevons donc l'architecture logicielle de la partie serveur de notre système.
Tout d'abord , nous proposerons la structure du package de l'application. Selon l'énoncé des travaux, l'application consistera en un serveur Web qui fournira l'API REST et donnera les fichiers de notre application Web (nous écrirons plus tard SPA sur Vue). De plus, selon les TdR, nous devons réaliser plusieurs packages pour les fournisseurs d'entrepôts de données.
À ce stade, nous devrions nous attarder plus en détail. Comment puis-je offrir la possibilité de basculer entre les fournisseurs de certaines fonctionnalités dans Go? Réponse: utiliser des interfaces. Ainsi, nous devrons développer une interface (contrat) pour les packages, chacun exécutant un contrat pour son propre type de stockage. Dans l'article, nous envisagerons de stocker des données dans la RAM, mais par analogie, vous pouvez facilement ajouter n'importe quel SGBD. La structure finale du package sera la suivante:
Deuxièmement , décidons des types de données dans lesquelles nous stockerons les informations reçues et du contrat pour les fournisseurs de stockage.
Nous aurons besoin de types de données pour les cotations boursières et l'inflation. Nous prendrons les cotations et l'inflation par mois, cette échelle est tout à fait adaptée à un instrument non spéculatif tel que l'ETF.
Le contrat nécessitera la disponibilité de méthodes pour remplir le stockage avec les données du serveur Mosbirzha (initialisation) et fournir des données de devis sur demande. Tout est extrêmement simple.
En conséquence, nous mettons les types de stockage des devis et l'interface dans le module de stockage:
Pour simplifier, nous codons les données d'inflation dans le module serveur:
var inflation = []struct { Year int Values [12]float64 }{ { Year: 2013, Values: [12]float64{0.97, 0.56, 0.34, 0.51, 0.66, 0.42, 0.82, 0.14, 0.21, 0.57, 0.56, 0.51}, }, { Year: 2014, Values: [12]float64{0.59, 0.70, 1.02, 0.90, 0.90, 0.62, 0.49, 0.24, 0.65, 0.82, 1.28, 2.62}, }, { Year: 2015, Values: [12]float64{3.85, 2.22, 1.21, 0.46, 0.35, 0.19, 0.80, 0.35, 0.57, 0.74, 0.75, 0.77}, }, { Year: 2016, Values: [12]float64{0.96, 0.63, 0.46, 0.44, 0.41, 0.36, 0.54, 0.01, 0.17, 0.43, 0.44, 0.40}, }, { Year: 2017, Values: [12]float64{0.62, 0.22, 0.13, 0.33, 0.37, 0.61, 0.07, -0.54, -0.15, 0.20, 0.22, 0.42}, }, { Year: 2018, Values: [12]float64{0.31, 0.21, 0.29, 0.38, 0.38, 0.49, 0.27, 0.01, 0.16, 0.35, 0.50, 0.84}, }, }
Troisièmement , décrivons les points de terminaison de notre API. Il n'y en aura que deux: pour les cotations et l'inflation. Seule méthode HTTP GET.
En effet, la réception et le traitement des données du site Internet Mosbirzi s'effectuent selon la méthode d'initialisation. Nous prenons les données en fonction de l'
aide sur l'API d'échange .
Ce à quoi vous devez faire attention: nous sommes obligés d'utiliser une demande distincte pour chaque titre (et il y en a déjà quelques dizaines). L'exécution de l'initialisation des données de manière séquentielle, dans un seul thread, prendrait beaucoup de temps. Par conséquent, nous utiliserons la fierté des goroutins. Faites attention au morceau de code suivant:
Dans la fonction d'initialisation des données, nous avons parallélisé les requêtes au serveur. En pratique, une telle analyse de site présente un certain nombre de problèmes:
- Peut entraîner le blocage automatique des demandes en raison d'une suspicion de DoS
- Vous devez utiliser le module de contexte ou le canal de contrôle pour forcer la fermeture de goroutin.
- Vous devez utiliser le canal pour renvoyer les erreurs de goroutine
Par souci de simplicité, tous ces points sont omis.
Aux fins du programme, le routeur de requête HTTP intégré nous suffit. Sur des systèmes plus complexes, vous voudrez probablement en utiliser d'autres. Personnellement, j'utilise le routeur du projet Gorilla, mais en général ils sont pleins.
Par la suite, nous ajouterons un point pour télécharger les fichiers de notre application Web. Pour l'avenir, je dirai que pour cela, vous devez simplement utiliser le retour du contenu du fichier.
Écrivons donc notre serveur:
Je ne fournirai pas ici le code d'implémentation du stockage, tout est disponible sur
Github .
Pour tester notre API:
l'inflationcitationsCeci termine la première partie de l'article. Dans la deuxième partie, nous écrirons des tests et des mesures de performances pour nos packages. Dans la troisième partie, nous développerons une application web.