0 Abonnés · 78 Publications

Choisissez la balise si vous souhaitez publier un élément qui ne concerne pas les plateformes ou les services de données d'InterSystems. 

Annonce Irène Mykhailova · Sept 18, 2022

La saison des hackathon d'automne arrive!

InterSystems participera au HackMIT hackathon - un hackathon d'un week-end par le MIT où des milliers d'étudiants se réunissent pour travailler sur des logiciels sympas et / ou des projets matériels. Cette année, Hackmit est de retour en pleine personne sur le campus du MIT pendant le week-end du 1er octobre.

 

0
0 56
Article Lucas Enard · Sept 18, 2022 8m read

1. Fhir-client-net

Ceci est un client fhir simple en c# pour s'exercer avec les ressources fhir et les requêtes CRUD vers un serveur fhir.
Notez que pour la majeure partie, l'autocomplétion est activée.

GitHub

2. Préalables

Assurez-vous que git et Docker desktop sont installé.

Si vous travaillez à l'intérieur du conteneur, ces modules sont déjà installés.
Si ce n'est pas le cas, utilisez nugget pour installer Hl7.Fhir.R4, nous allons utiliser Model et Rest à partir de celui-ci :
Hl7.Fhir.Model

Hl7.Fhir.Rest

3. Installation

3.1. Installation pour le développement

Clone/git tire le repo dans n'importe quel répertoire local, par exemple comme indiqué ci-dessous :

git clone https://github.com/LucasEnard/fhir-client-net.git

Ouvrez le terminal dans ce répertoire et lancez :

docker build .

3.2. Portail de gestion et VSCode

Ce référentiel est prêt pour VS Code.

Ouvrez le dossier fhir-client-net cloné localement dans VS Code.

Si vous y êtes invité (coin inférieur droit), installez les extensions recommandées.

3.3. Avoir le dossier ouvert à l'intérieur du conteneur

Vous pouvez être à l'intérieur du conteneur avant de coder si vous le souhaitez.
Pour cela, il faut que docker soit activé avant d'ouvrir VSCode.
Ensuite, dans VSCode, lorsque vous y êtes invité ( coin inférieur droit ), rouvrez le dossier à l'intérieur du conteneur afin de pouvoir utiliser les composants python qu'il contient.
La première fois que vous effectuez cette opération, cela peut prendre plusieurs minutes, le temps que le conteneur soit préparé.

Si vous n'avez pas cette option, vous pouvez cliquer dans le coin inférieur gauche et cliquer sur press reopen in container puis sélectionner From Dockerfile

Plus d'informations ici

Architecture


En ouvrant le dossier à distance, vous permettez à VS Code et à tous les terminaux que vous ouvrez dans ce dossier d'utiliser les composants c# dans le conteneur.

Si vous y êtes invité (coin inférieur droit), installez les extensions recommandées.

4. Serveur FHIR

Pour réaliser cette présentation, vous aurez besoin d'un serveur FHIR.
Vous pouvez soit utiliser le vôtre, soit vous rendre sur le site InterSystems free FHIR trial et suivre les étapes suivantes pour le configurer.

En utilisant notre essai gratuit, il suffit de créer un compte et de commencer un déploiement, puis dans l'onglet Overview vous aurez accès à un endpoint comme https://fhir.000000000.static-test-account.isccloud.io que nous utiliserons plus tard.
Ensuite, en allant dans l'onglet d'informations d'identification Credentials, créez une clé api et enregistrez-la quelque part.

C'est maintenant terminé, vous avez votre propre serveur fhir pouvant contenir jusqu'à 20 Go de données avec une mémoire de 8 Go.

5. Présentation pas à pas

La présentation pas à pas du client se trouve à /Client.cs.

Le code est divisé en plusieurs parties, et nous allons couvrir chacune d'entre elles ci-dessous.

5.1. Partie 1

Dans cette partie, nous connectons notre client à notre serveur en utilisant Fhir.Rest.


// Partie 1

// Creation of an htpclient holding the api key of the server as an header
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("x-api-key", "api-key");

var settings = new FhirClientSettings
    {
        Timeout = 0,
        PreferredFormat = ResourceFormat.Json,
        VerifyFhirVersion = true,
        // PreferredReturn can take Prefer.ReturnRepresentation or Prefer.ReturnMinimal to return the full resource or an empty payload
        PreferredReturn = Prefer.ReturnRepresentation
    };
// Création de notre client en utilisant une correcte url
var client = new FhirClient("url",httpClient,settings);

Afin de vous connecter à votre serveur, vous devez modifier la ligne :

httpClient.DefaultRequestHeaders.Add("x-api-key", "api-key");

Et cette ligne aussi :

var client = new FhirClient("url",httpClient,settings);

L'url' est un point de terminaison tandis que l'"api-key" est la clé d'api pour accéder à votre serveur.

Notez que si vous n'utilisez pas un serveur InterSystems, vous pouvez vérifier comment autoriser vos accès si nécessaire.

Comme ça, nous avons un client FHIR capable d'échanger directement avec notre serveur.

5.2. Partie 2

Dans cette partie, nous créons un Patient en utilisant Fhir.Model et nous le complétons avec un HumanName, en suivant la convention FHIR, use et family sont des chaînes et given est une liste de chaînes. De la même manière, un patient peut avoir plusieurs HumanNames, donc nous devons mettre notre HumanName dans une liste avant de le mettre dans notre patient nouvellement créé.


// Partie 2

// Building a new patient and setting the names
var patient0 = new Patient();
patient0.Name.Add(new HumanName().WithGiven("GivenName").AndFamily("FamilyName"));

// Creation of our client in the server
// It is to be noted that using SearchParams you can check if an equivalent resource already exists in the server
// For more information https://docs.fire.ly/projects/Firely-NET-SDK/client/crud.html
var created_pat = client.Create<Patient>(patient0);

Console.Write("Partie 2 : Identifiant du patient nouvellement créé : ");
Console.WriteLine(created_pat.Id);

Après cela, nous devons sauvegarder notre nouveau Patient sur notre serveur en utilisant notre client.

Notez que si vous lancez Client.cs plusieurs fois, plusieurs Patients ayant le nom que nous avons choisi seront créés.
C'est parce que, suivant la convention FHIR, vous pouvez avoir plusieurs Patients avec le même nom, seul l' id est unique sur le serveur.
Vérifier la documentation pour avoir plus d'information.
Il est à noter qu'en utilisant SearchParams vous pouvez vérifier si une ressource équivalente existe déjà sur le serveur avant de la créer.
Pour plus d'information https://docs.fire.ly/projects/Firely-NET-SDK/client/crud.html

Nous conseillons donc de commenter la ligne après le premier lancement.

5.3. Partie 3

Dans cette partie, nous avons un client qui recherche un patient nommé d'après celui que nous avons créé précédemment.


// Part 3

// This gets all the Patient having the exact name "FamilyName" and we take the first one
// Note that if you have multiple patients with the same name, you will get only the first one 
// We advise to use the id, the names, and any other informations for the SearchParams to be sure to get the right patient
var q = new SearchParams().Where("name:exact=FamilyName");
Bundle bund = client.Search<Patient>(q);
patient0 = bund.Entry[0].Resource as Patient;

Console.Write("Part 3 : Name of the patient we found by searching : ");
Console.WriteLine(patient0.Name[0]);


// Creation of our patient telecom, here a phone number
patient0.Telecom.Add(new ContactPoint(new ContactPoint.ContactPointSystem(),new ContactPoint.ContactPointUse(),"1234567890"));

// Change the given name of our patient
patient0.Name[0].Given = new List<string>() { "AnotherGivenName" };

Console.Write("Part 3 : Name of the changed patient : ");
Console.WriteLine(patient0.Name[0]);

Console.Write("Part 3 : Phone of the changed patient : ");
Console.WriteLine(patient0.Telecom[0].Value);

// Update the patient
var update_pat = client.Update<Patient>(patient0);

Une fois que nous l'avons trouvé, nous ajoutons un numéro de téléphone à son profil et nous changeons son prénom en un autre.

Maintenant nous pouvons utiliser la fonction de mise à jour de notre client pour mettre à jour notre patient sur le serveur.

5.4. Partie 4

Dans cette section, nous voulons créer une observation pour notre patient. Pour ce faire, nous avons besoin de son identifiant, qui est son identifiant unique.
A partir de là, nous remplissons notre observation et ajoutons comme sujet, l'identifiant de notre Patient.


// Part 4

// Building of our new observation
Observation obsv = new Observation {

    Value = new Quantity(70, "kg"),
    Code = new CodeableConcept {
        Coding = new List<Coding> {
            new Coding {
                System = "http://loinc.org",
                Code = "29463-7",
                Display = "Body weight"
            }
        }},
    Category = new List<CodeableConcept> {
        new CodeableConcept {
            Coding = new List<Coding> {
                new Coding {
                    System = "http://snomed.info/sct",
                    Code = "276327007",
                    Display = "Body weight"
                }
            }
        }},
    Status = new ObservationStatus {},
    Subject = new ResourceReference {
        Reference = "Patient/" + update_pat.Id}

    };

// Creation of our observation in the server
var new_obsv = client.Create<Observation>(obsv);

Console.Write("Part 4 : Id of the observation : ");
Console.WriteLine(new_obsv.Id);

Ensuite, nous enregistrons notre observation à l'aide de la fonction create.

5.5. Conclusion de la présentation

Si vous avez suivi ce parcours, vous savez maintenant exactement ce que fait Client.cs, vous pouvez le lancer et vérifier votre Patient et votre Observation nouvellement créés sur votre serveur.

Pour le lancer, ouvrez un terminal VSCode et entrez :

dotnet run

Vous devriez voir des informations sur le Patient créé et son observation.

Si vous utilisez un serveur Intersystems, allez à API Deployement, autorisez-vous avec la clé api et d'ici vous pouvez OBTENIR par id le patient et l'observation que nous venons de créer.

7. Comment commencer le codage

Ce référentiel est prêt à être codé dans VSCode avec les plugins InterSystems. Ouvrez Client.cs pour commencer à coder ou utiliser l'autocomplétion.

8. Ce qu'il y a dans le référentiel

8.1. Dockerfile

Un dockerfile pour créer un dot net env pour que vous puissiez travailler.
Utilisez docker build . pour construire et rouvrir votre fichier dans le conteneur pour travailler à l'intérieur de celui-ci.

8.2. .vscode/settings.json

Fichier de paramètres

8.3. .vscode/launch.json

Fichier de configuration si vous voulez déboguer

0
0 183
Article Lucas Enard · Sept 14, 2022 12m read

1. Fhir-client-python

Ceci est un client fhir simple en python pour s'exercer avec les ressources fhir et les requêtes CRUD vers un serveur FHIR.
Notez que pour la plupart, l'autocomplétion est activée, c'est la principale raison d'utiliser fhir.resources.

GitHub

2. Préalables

Assurez-vous que git et Docker desktop sont installé.

Si vous travaillez à l'intérieur du conteneur, comme il est montré dans 3.3., vous n'avez pas besoin d'installer fhirpy et fhir.resources.

Si vous n'êtes pas dans le conteneur, vous pouvez utiliser pip pour installer fhirpy et fhir.resources.
Vérifiez fhirpy et fhir.resources pour plus d'information.

3. Installation

3.1. Installation pour le développement

Clone/git tire le repo dans n'importe quel répertoire local, par exemple comme indiqué ci-dessous :

git clone https://github.com/LucasEnard/fhir-client-python.git

Ouvrez le terminal dans ce répertoire et lancez :

docker build.

3.2. Portail de gestion et VSCode

Ce référentiel est prêt pour VS Code.

Ouvrez le dossier fhir-client-python cloné localement dans VS Code.

Si vous y êtes invité (coin inférieur droit), installez les extensions recommandées.

3.3. Avoir le dossier ouvert à l'intérieur du conteneur

Vous pouvez être à l'intérieur du conteneur avant de coder si vous le souhaitez.
Pour cela, il faut que docker soit activé avant d'ouvrir VSCode.
Ensuite, dans VSCode, lorsque vous y êtes invité ( coin inférieur droit ), rouvrez le dossier à l'intérieur du conteneur afin de pouvoir utiliser les composants python qu'il contient.
La première fois que vous effectuez cette opération, cela peut prendre plusieurs minutes, le temps que le conteneur soit préparé.

Si vous n'avez pas cette option, vous pouvez cliquer dans le coin inférieur gauche et cliquer sur Ouvrir à nouveau dans le conteneur puis sélectionner De Dockerfile

Plus d'informations ici

Architecture


En ouvrant le dossier à distance, vous permettez à VS Code et à tous les terminaux que vous ouvrez dans ce dossier d'utiliser les composants python dans le conteneur.

4. Serveur FHIR

Pour réaliser cette présentation, vous aurez besoin d'un serveur FHIR.
Vous pouvez soit utiliser le vôtre, soit vous rendre sur le site InterSystems free FHIR trial et suivre les étapes suivantes pour le configurer.

En utilisant notre essai gratuit, il suffit de créer un compte et de commencer un déploiement, puis dans l'onglet Overview vous aurez accès à un endpoint comme https://fhir.000000000.static-test-account.isccloud.io que nous utiliserons plus tard.
Ensuite, en allant dans l'onglet d'informations d'identification Credentials, créez une clé api et enregistrez-la quelque part.

C'est maintenant terminé, vous avez votre propre serveur fhir pouvant contenir jusqu'à 20 Go de données avec une mémoire de 8 Go.

5. Présentation pas à pas

La présentation pas à pas du client se trouve à src/client.py.

Le code est divisé en plusieurs parties, et nous allons couvrir chacune d'entre elles ci-dessous.

5.1. Partie 1

Dans cette partie, nous connectons notre client à notre serveur en utilisant fhirpy et nous obtenons nos ressources Patient à l'intérieur de la variable patients_resources.
A partir de cette variable nous pourrons fecth n'importe quel Patient et même les trier ou obtenir un Patient en utilisant certaines conditions.

#Partie 1----------------------------------------------------------------------------------------------------------------------------------------------------
#Créer notre client connecté à notre serveur
client = SyncFHIRClient(url='url', extra_headers={"x-api-key":"api-key"})

#Obtenir les ressources de notre patient dans lesquelles nous pourrons aller chercher et rechercher
patients_resources = client.resources('Patient')

Afin de vous connecter à votre serveur, vous devez modifier la ligne :

client = SyncFHIRClient(url='url', extra_headers={"x-api-key":"api-key"})

L'url' est un point de terminaison tandis que l'"api-key" est la clé d'api pour accéder à votre serveur.

Notez que si vous n'utilisez pas un serveur InterSystems, vous pouvez vérifier comment changer extra_headers={"x-api-key":"api-key"} en authorization = "api-key".

Comme ça, nous avons un client FHIR capable d'échanger directement avec notre serveur.

5.2. Partie 2

Dans cette partie, nous créons un Patient en utilisant Fhir.Model et nous le complétons avec un HumanName, en suivant la convention FHIR, use et family sont des chaînes et given est une liste de chaînes. e la même manière, un patient peut avoir plusieurs HumanNames, donc nous devons mettre notre HumanName dans une liste avant de le mettre dans notre patient nouvellement créé.

#Partie 2----------------------------------------------------------------------------------------------------------------------------------------------------
#Nous voulons créer un patient et l'enregistrer sur notre serveur

#Créer un nouveau patient en utilisant fhir.resources
patient0 = Patient()

#Créer un HumanName et le remplir avec les informations de notre patient
name = HumanName()
name.use = "official"
name.family = "familyname"
name.given = ["givenname1","givenname2"]

patient0.name = [name]

#Vérifier notre patient dans le terminal
print()
print("Our patient : ",patient0)
print()

#Sauvegarder (post) notre patient0, cela va le créer sur notre serveur
client.resource('Patient',**json.loads(patient0.json())).save()

Après cela, nous devons sauvegarder notre nouveau Patient sur notre serveur en utilisant notre client.

Notez que si vous lancez client.py plusieurs fois, plusieurs Patients ayant le nom que nous avons choisi seront créés.
C'est parce que, suivant la convention FHIR, vous pouvez avoir plusieurs Patients avec le même nom, seul l' id est unique sur le serveur.
Alors pourquoi n'avons-nous pas rempli notre Patient avec un id de la même façon que nous avons rempli son nom ?
Parce que si vous mettez un id à l'intérieur de la fonction save(), la sauvegarde agira comme une mise à jour avant d'agir comme un sauveur, et si l'id n'est en fait pas déjà sur le serveur, il le créera comme prévu ici. Mais comme nous avons déjà des patients sue notre serveur, ce n'est pas une bonne idée de créer un nouveau patient et d'allouer à la main un Identifiant puisque la fonction save() et le serveur sont faits pour le faire à votre place.

Nous conseillons donc de commenter la ligne après le premier lancement.

5.3. Partie 3

Dans cette partie, nous avons un client qui cherche dans nos patients_resources un patient nommé d'après celui que nous avons créé précédemment.

#Partie 3----------------------------------------------------------------------------------------------------------------------------------------------------
#Maintenant, nous voulons obtenir un certain patient et ajouter son numéro de téléphone et changer son nom avant de sauvegarder nos changements sur le serveur

#Obtenez le patient en tant que fhir.resources Patient de notre liste de ressources de patients qui a le bon nom, pour la commodité, nous allons utiliser le patient que nous avons créé avant
patient0 = Patient.parse_obj(patients_resources.search(family='familyname',given='givenname1').first().serialize())

#Créer le nouveau numéro de téléphone de notre patient
telecom = ContactPoint()

telecom.value = '555-748-7856'
telecom.system = 'phone'
telecom.use = 'home'

#Ajouter le téléphone de notre patient à son dossier
patient0.telecom = [telecom]

#Changer le deuxième prénom de notre patient en "un autre prénom"
patient0.name[0].given[1] = "anothergivenname"

#Vérifiez notre Patient dans le terminal
print()
print("Notre patient avec le numéro de téléphone et le nouveau prénom : ",patient0)
print()

#Sauvegarder (mettre) notre patient0, ceci sauvera le numéro de téléphone et le nouveau prénom au patient existant de notre serveur
client.resource('Patient',**json.loads(patient0.json())).save()

Une fois que nous l'avons trouvé, nous ajoutons un numéro de téléphone à son profil et nous changeons son prénom en un autre.

Maintenant nous pouvons utiliser la fonction de mise à jour de notre client pour mettre à jour notre patient sur le serveur.

5.4. Partie 4

Dans cette partie, nous voulons créer une observation pour notre patient précédent, pour ce faire, nous cherchons d'abord notre patients_resources pour notre patient, puis nous obtenons son identifiant, qui est son identificateur unique.

#Partie 4----------------------------------------------------------------------------------------------------------------------------------------------------
#Maintenant nous voulons créer une observation pour notre client

#Obtenir l'identifiant du patient auquel vous voulez attacher l'observation
id = Patient.parse_obj(patients_resources.search(family='familyname',given='givenname1').first().serialize()).id
print("id of our patient : ",id)

#Placer notre code dans notre observation, code qui contient des codages qui sont composés de système, code et affichage
coding = Coding()
coding.system = "https://loinc.org"
coding.code = "1920-8"
coding.display = "Aspartate aminotransférase [Activité enzymatique/volume] dans le sérum ou le plasma"
code = CodeableConcept()
code.coding = [coding]
code.text = "Aspartate aminotransférase [Activité enzymatique/volume] dans le sérum ou le plasma"

#Créer une nouvelle observation en utilisant fhir.resources, nous entrons le statut et le code dans le constructeur car ils sont nécessaires pour valider une observation
observation0 = Observation(status="final",code=code)

#Définir notre catégorie dans notre observation, catégorie qui détient les codages qui sont composés de système, code et affichage
coding = Coding()
coding.system = "https://terminology.hl7.org/CodeSystem/observation-category"
coding.code = "laboratoire"
coding.display = "laboratoire"
category = CodeableConcept()
category.coding = [coding]
observation0.category = [category]

#Définir l'heure de notre date effective dans notre observation
observation0.effectiveDateTime = "2012-05-10T11:59:49+00:00"

#Régler l'heure de notre date d'émission dans notre observation
observation0.issued = "2012-05-10T11:59:49.565+00:00"

#Définir notre valueQuantity dans notre observation, valueQuantity qui est composée d'un code, d'un unir, d'un système et d'une valeur
valueQuantity = Quantity()
valueQuantity.code = "U/L"
valueQuantity.unit = "U/L"
valueQuantity.system = "https://unitsofmeasure.org"
valueQuantity.value = 37.395
observation0.valueQuantity = valueQuantity

#Définir la référence à notre patient en utilisant son identifiant
reference = Reference()
reference.reference = f"Patient/{id}"
observation0.subject = reference

#Vérifiez notre observation dans le terminal
print()
print("Notre observation : ",observation0)
print()

#Sauvegarder (poster) notre observation0 en utilisant notre client
client.resource('Observation',**json.loads(observation0.json())).save()

Ensuite, nous enregistrons notre observation à l'aide de la fonction save().

5.5. Conclusion de la présentation

Si vous avez suivi ce parcours, vous savez maintenant exactement ce que fait client.py, vous pouvez le lancer et vérifier votre Patient et votre Observation nouvellement créés sur votre serveur.

6. Comment ça marche

6.1. Les importations

from fhirpy import SyncFHIRClient

from fhir.resources.patient import Patient
from fhir.resources.observation import Observation
from fhir.resources.humanname import HumanName
from fhir.resources.contactpoint import ContactPoint

import json

La première importation est le client, ce module va nous aider à nous connecter au serveur, à obtenir et exporter des ressources.

Le module fhir.resources nous aide à travailler avec nos ressources et nous permet, grâce à l'auto-complétion, de trouver les variables dont nous avons besoin.

La dernière importation est json, c'est un module nécessaire pour échanger des informations entre nos 2 modules.

6.2. Création du client

client = SyncFHIRClient(url='url', extra_headers={"x-api-key":"api-key"})

L''url' est ce que nous avons appelé avant un point de terminaison tandis que l'"api-key"' est la clé que vous avez générée plus tôt.

Notez que si vous n'utilisez pas un serveur InterSystems, vous voudrez peut-être changer le extra_headers={"x-api-key" : "api-key"} en authorization = "api-key"
Comme ça, nous avons un client FHIR capable d'échanger directement avec notre serveur.

Par exemple, vous pouvez accéder à vos ressources Patient en faisant patients_resources = client.resources('Patient') , fà partir de là, vous pouvez soit obtenir vos patients directement en utilisant patients = patients_resources.fetch() ou en allant chercher après une opération, comme :
patients_resources.search(family='familyname',given='givenname').first() cette ligne vous donnera le premier patient qui sort ayant pour nom de famille 'familyname' et pour nom donné 'givenname'.

6.3. Travailler sur nos ressources

Une fois que vous avez les ressources que vous voulez, vous pouvez les analyser dans une ressource fhir.resources.

Par exemple :

patient0 = Patient.parse_obj(patients_resources.search(family='familyname',given='givenname1').first().serialize())

patient0 est un patient de fhir.resources, pour l'obtenir nous avons utilisé nos patients_resources comme cela a été montré précédemment où nous avons sélectionné un certain nom de famille et un prénom, après cela nous avons pris le premier qui est apparu et l'avons sérialisé.
En mettant ce patient sérialisé à l'intérieur d'un Patient.parse_obj nous allons créer un patient de fhir.resources .

Maintenant, vous pouvez accéder directement à n'importe quelle information que vous voulez comme le nom, le numéro de téléphone ou toute autre information.
Pour ce faire, utilisez juste par exemple :

patient0.name

Cela renvoie une liste de HumanName composée chacune d'un attribut use un attribut family un attribut given as the FHIR convention is asking.
Cela signifie que vous pouvez obtenir le nom de famille de quelqu'un en faisant :

patient0.name[0].family

6.4. Sauvegarder nos changements

Pour enregistrer toute modification de notre serveur effectuée sur un fhir.resources ou pour créer une nouvelle ressource serveur, nous devons utiliser à nouveau notre client.

client.resource('Patient',**json.loads(patient0.json())).save()

En faisant cela, nous créons une nouvelle ressource sur notre client, c'est-à-dire un patient, qui obtient ses informations de notre fhir.resources patient0. Ensuite, nous utilisons la fonction save() pour poster ou mettre notre patient sur le serveur.

7. Comment commencer le codage

Ce référentiel est prêt à être codé dans VSCode avec les plugins InterSystems. Ouvrez /src/client.py pour commencer à coder ou utiliser l'autocomplétion.

8. Ce qu'il y a dans le référentiel

8.1. Dockerfile

Le dockerfile le plus simple pour démarrer un conteneur Python.
Utilisez docker build . pour construire et rouvrir votre fichier dans le conteneur pour travailler à l'intérieur de celui-ci.

8.2. .vscode/settings.json

Fichier de paramètres.

8.3. .vscode/launch.json

Fichier de configuration si vous voulez déboguer.

0
0 808
Article Lucas Enard · Sept 12, 2022 9m read

1. Fhir-client-java

Ceci est un client fhir simple en java pour s'exercer avec les ressources fhir et les requêtes CRUD vers un serveur fhir.
Notez que pour la majeure partie, l'autocomplétion est activée.

GitHub

2. Préalables

Assurez-vous que git et Docker desktop sont installé.

Déjà installé dans le conteneur :
Hapi Fhir modèle et client

3. Installation

3.1. Installation pour le développement

Clone/git tire le repo dans n'importe quel répertoire local, par exemple comme indiqué ci-dessous :

git clone https://github.com/LucasEnard/fhir-client-java.git

Ouvrez le terminal dans ce répertoire et exécutez :

docker build .

3.2. Portail de gestion et VSCode

Ce référentiel est prêt pour CodeVS.

Ouvrez le dossier fhir-client-java cloné localement dans VS Code.

Si vous y êtes invité (coin inférieur droit), installez les extensions recommandées.

3.3. Avoir le dossier ouvert à l'intérieur du conteneur

Vous pouvez être à l'intérieur du conteneur avant de coder si vous le souhaitez.
Pour cela, il faut que docker soit activé avant d'ouvrir VSCode.
Ensuite, dans VSCode, lorsque vous y êtes invité ( coin inférieur droit ), rouvrez le dossier à l'intérieur du conteneur afin de pouvoir utiliser les composants python qu'il contient.
La première fois que vous effectuez cette opération, cela peut prendre plusieurs minutes, le temps que le conteneur soit préparé.

Si vous n'avez pas cette option, vous pouvez cliquer dans le coin inférieur gauche et cliquer sur Ouvrir à nouveau dans le conteneur puis sélectionner De Dockerfile

Plus d'informations ici

Architecture


En ouvrant le dossier à distance, vous permettez à VS Code et à tous les terminaux que vous ouvrez dans ce dossier d'utiliser les composants java dans le conteneur.

4. Serveur FHIR

Pour réaliser cette présentation, vous aurez besoin d'un serveur FHIR.
Vous pouvez soit utiliser le vôtre, soit vous rendre sur le site Essai FHIR gratuit d'InterSystems et suivre les étapes suivantes pour le configurer.

En utilisant notre essai gratuit, il suffit de créer un compte et de commencer un déploiement, puis dans l'onglet Overview vous aurez accès à un endpoint comme https://fhir.000000000.static-test-account.isccloud.io que nous utiliserons plus tard.
Ensuite, en allant dans l'onglet d'informations d'identification Credentials, créez une clé api et enregistrez-la quelque part.

C'est maintenant terminé, vous avez votre propre serveur fhir pouvant contenir jusqu'à 20 Go de données avec une mémoire de 8 Go.

5. Présentation pas à pas

La présentation pas à pas du client se trouve à src/java/test/Client.java.

Le code est divisé en plusieurs parties, et nous allons couvrir chacune d'entre elles ci-dessous.

5.1. Partie 1

Dans cette partie, nous connectons notre client à notre serveur en utilisant Fhir.Rest.


// Partie 1

      // Créer un contexte en utilisant FHIR R4
      FhirContext ctx = FhirContext.forR4();

      // créer un en-tête contenant la clé api pour le httpClient
      Header header = new BasicHeader("x-api-key", "api-key");
      ArrayList<Header> headers = new ArrayList<Header>();
      headers.add(header);

      // créer un constructeur httpClient et lui ajouter l'en-tête
      HttpClientBuilder builder = HttpClientBuilder.create();
      builder.setDefaultHeaders(headers);

      // créer un httpClient à l'aide du constructeur
      CloseableHttpClient httpClient = builder.build();

      // Configurer le httpClient au contexte en utilisant la fabrique
      ctx.getRestfulClientFactory().setHttpClient(httpClient);

      // Créer un client
      IGenericClient client = ctx.newRestfulGenericClient("url");

Afin de vous connecter à votre serveur, vous devez modifier la ligne :

Header header = new BasicHeader("x-api-key", "api-key");

Et cette ligne aussi :

IGenericClient client = ctx.newRestfulGenericClient("url");

L'url' est un point de terminaison tandis que l'"api-key" est la clé d'api pour accéder à votre serveur.

Notez que si vous n'utilisez pas un serveur InterSystems, vous pouvez vérifier comment autoriser vos accès si nécessaire.

Comme ça, nous avons un client FHIR capable d'échanger directement avec notre serveur.

5.2. Partie 2

Dans cette partie, nous créons un Patient en utilisant Fhir.Model et nous le complétons avec un HumanName, en suivant la convention FHIR, use et family sont des chaînes et given est une liste de chaînes. De la même manière, un patient peut avoir plusieurs HumanNames, donc nous devons mettre notre HumanName dans une liste avant de le mettre dans notre patient nouvellement créé.


// Partie 2

      // Créer un patient et lui ajouter un nom
      Patient patient = new Patient();
      patient.addName()
         .setFamily("FamilyName")
         .addGiven("GivenName1")
         .addGiven("GivenName2");

      // Voir aussi patient.setGender ou setBirthDateElement

      // Créer le patient ressource sur le serveur
		MethodOutcome outcome = client.create()
         .resource(patient)
         .execute();

      // Enregistrez l'ID que le serveur a attribué
      IIdType id = outcome.getId();
      System.out.println("");
      System.out.println("Created patient, got ID: " + id);
      System.out.println("");

Après cela, nous devons sauvegarder notre nouveau Patient sur notre serveur en utilisant notre client.

Notez que si vous lancez Client.java plusieurs fois, plusieurs Patients ayant le nom que nous avons choisi seront créés.
C'est parce que, suivant la convention FHIR, vous pouvez avoir plusieurs Patients avec le même nom, seul l' id est unique sur le serveur.
Vérifier the doc pour avoir plus d'information.
Nous conseillons donc de commenter la ligne après le premier lancement.

5.3. Partie 3

Dans cette partie, nous avons un client qui recherche un patient nommé d'après celui que nous avons créé précédemment.

// Partie 3

      // Rechercher un patient unique avec le nom de famille exact "NomDeFamille" et le prénom exact "Prénom1"
      patient = (Patient) client.search()
         .forResource(Patient.class)
         .where(Patient.FAMILY.matchesExactly().value("FamilyName"))
         .and(Patient.GIVEN.matchesExactly().value("GivenName1"))
         .returnBundle(Bundle.class)
         .execute()
         .getEntryFirstRep()
         .getResource();

      // Créer une télécommunication pour le patient
      patient.addTelecom()
         .setSystem(ContactPointSystem.PHONE)
         .setUse(ContactPointUse.HOME)
         .setValue("555-555-5555");

      // Changer le prénom du patient en un autre
      patient.getName().get(0).getGiven().set(0,  new StringType("AnotherGivenName"));

      // Mettre à jour le patient de ressource sur le serveur
      MethodOutcome outcome2 = client.update()
         .resource(patient)
         .execute();

Une fois que nous l'avons trouvé, nous ajoutons un numéro de téléphone à son profil et nous changeons son prénom en un autre.

Maintenant nous pouvons utiliser la fonction de mise à jour de notre client pour mettre à jour notre patient sur le serveur.

5.4. Partie 4

Dans cette section, nous voulons créer une observation pour notre patient. Pour ce faire, nous avons besoin de son identifiant, qui est son identifiant unique.
A partir de là, nous remplissons notre observation et ajoutons comme sujet, l'identifiant de notre Patient.

// Partie 4

      // Créer un CodeableConcept et le remplir
      CodeableConcept codeableConcept = new CodeableConcept();
      codeableConcept.addCoding()
         .setSystem("http://snomed.info/sct")
         .setCode("1234")
         .setDisplay("CodeableConceptDisplay");

      // Créer une quantité et la remplir
      Quantity quantity = new Quantity();
      quantity.setValue(1.0);
      quantity.setUnit("kg");

      // Créer une catégorie et la remplir
      CodeableConcept category = new CodeableConcept();
      category.addCoding()
         .setSystem("http://snomed.info/sct")
         .setCode("1234")
         .setDisplay("CategoryDisplay");

      // Créer une liste de CodeableConcepts et y placer des catégories
      ArrayList<CodeableConcept> codeableConcepts = new ArrayList<CodeableConcept>();
      codeableConcepts.add(category);

      // Créer une observation
      Observation observation = new Observation();
      observation.setStatus(Observation.ObservationStatus.FINAL);
      observation.setCode(codeableConcept);
      observation.setSubject(new Reference().setReference("Patient/" + ((IIdType) outcome2.getId()).getIdPart()));
      observation.setCategory(codeableConcepts);
      observation.setValue(quantity);

      System.out.println("");
      System.out.println("Created observation, reference : " + observation.getSubject().getReference());
      System.out.println("");

       // Créer l'observation de ressource sur le serveur
      MethodOutcome outcome3 = client.create()
         .resource(observation)
         .execute();

      // Imprimer la réponse du serveur
      System.out.println("");
      System.out.println("Created observation, got ID: " + outcome3.getId());
      System.out.println("");

Ensuite, nous enregistrons notre observation à l'aide de la fonction de création.

5.5. Conclusion de la présentation

Si vous avez suivi ce parcours, vous savez maintenant exactement ce que fait Client.java, vous pouvez le lancer et vérifier votre Patient et votre Observation nouvellement créés sur votre serveur.

Pour le lancer, ouvrez un terminal VSCode et entrez :

dotnet run

Vous devriez voir des informations sur le Patient créé et son observation.

Si vous utilisez un serveur Intersystems, allez à API Deployement, autorisez-vous avec la clé api et d'ici vous pouvez OBTENIR par id le patient et l'observation que nous venons de créer.

6. Comment commencer le codage

Ce référentiel est prêt à être codé dans VSCode avec les plugins InterSystems. Ouvrez Client.java pour commencer à coder ou utiliser l'autocomplétion.

7. Ce qu'il y a dans le référentiel

7.1. Dockerfile

Un dockerfile pour créer un dot net env pour que vous puissiez travailler.
Utilisez docker build . pour construire et rouvrir votre fichier dans le conteneur pour travailler à l'intérieur de celui-ci.

7.2. .vscode/settings.json

Fichier de paramètres.

7.3. .vscode/launch.json

Fichier de configuration si vous voulez déboguer

0
0 220
Article Sergei Sarkisian · Juil 5, 2022 10m read

Avant de commencer à aborder des sujets intermédiaires et avancés, je voudrais résumer quelques points plus généraux. Ils sont subjectifs, bien sûr, et je serai heureux d'en discuter si vous avez une autre opinion ou de meilleurs arguments pour l'un d'entre eux.

La liste n'est pas exhaustive et c'est voulu, car je couvrirai certains sujets dans de futurs articles.

Conseil 1. Suivez le guide de style officiel

Angular est assez strict en termes de limitation de l'architecture possible d'une application, mais il y a encore de nombreux endroits qui vous permettent de faire les choses à votre façon. L'imagination des développeurs est sans limite, mais elle rend parfois le travail difficile pour ceux qui travaillent sur le projet avec vous ou après vous.

L'équipe Angular fait un bon travail en maintenant l'architecture Angular elle-même et ses bibliothèques, donc ils savent certainement comment créer une base de code stable et supportable.

Je recommande de suivre leur guide de style officiel et de ne s'en écarter que si les choses ne fonctionnent pas de cette façon. Cela rendra les choses plus faciles quand vous arriverez à un nouveau projet ou si quelqu'un arrive dans votre projet.

Rappelez-vous, un code et une architecture d'application supportables, stables et faciles à comprendre sont plus importants que des solutions intelligentes mais cryptiques que personne ne pourra rattraper (peut-être même vous à l'avenir).

Guide de style officiel d'Angular : https://angular.io/guide/styleguide

Conseil 2. Envisagez d'acheter le livre Angular Ninja

Vous pouvez penser que c'est de la pub, mais voilà : c'est un très bon livre avec tous les principaux concepts d'Angular et le prix est à votre convenance. Vous pouvez également choisir combien d'argent ira aux auteurs et combien ira à une œuvre de charité.

L'un des auteurs de ce livre est membre d'Angular teem, donc c'est certainement la source d'information la plus fiable sur Angular après la documentation officielle. Vous pouvez voir les chapitres du livre sur la page du livre et lire des exemples de chapitres pour décider si le livre en vaut la peine.

De plus, le livre est mis à jour avec la sortie d'une nouvelle version d'Angular et vous obtenez toutes les mises à jour du livre gratuitement.

Le blog Ninja Squad lui-même est une très bonne source d'informations sur Angular, avec des articles et des nouvelles sur les nouvelles versions, les meilleures pratiques, les fonctionnalités expérimentales et plus encore.

Le livre Angular Ninja : https://books.ninja-squad.com/angular

Conseil 3. Lisez la documentation officielle

Avant de vous plonger dans l'écriture du code de votre application, il est bon de lire la documentation et les guides officiels, surtout si vous démarrez votre projet sur une version d'Angular que vous n'avez jamais utilisée auparavant. Les choses sont dépréciées tout le temps, les tutoriels et les guides sur Internet peuvent être dépassés et vous pouvez finir par augmenter votre dette technique au lieu d'utiliser les nouvelles meilleures pratiques et fonctionnalités.

C'est aussi une bonne habitude de vérifier pour quelle version le guide a été écrit. S'il s'agit d'une version antérieure de plus de deux ans à celle que vous utilisez, il est préférable de vérifier si les choses ont changé depuis.

Documentation officielle : https://angular.io

Conseil 4. Envisagez d'utiliser Angular CDK même si vous n'utilisez pas Angular Material.

Je l'aborderai plus en détail dans de futurs articles, mais je sais que de nombreux développeurs Angular ne connaissent même pas Angular CDK.

Angular CDK est une bibliothèque de directives et de classes de base utiles qui peuvent vous aider à développer de meilleures applications. Par exemple, elle contient des éléments tels que FocusTrap, Drag & Drop, VirtualScroll et d'autres qui peuvent être facilement ajoutés à vos composants.

Angular CDK : https://material.angular.io/cdk/categories

Conseil 5. Fixez vos dépendances dans package.json

Il n'est pas particulièrement lié à Angular et il peut être important dans tout projet. Lorsque vous faites npm install --save <quelque chose> , il sera ajouté à votre package.json avec ^ ou ~ au début de la version du package. Cela signifie que votre projet sera capable d'utiliser n'importe quelle version mineure/patch de la même version majeure de la dépendance. Cela se passera mal à l'avenir avec une probabilité de presque 100%. J'ai été confronté à ce problème dans différents projets à de nombreuses reprises. Le temps passe et une nouvelle version mineure d'une dépendance sort et votre application ne se construit plus. Parce qu'un auteur de cette dépendance a mis à jour ses dépendances en version mineure (ou même en patch) et maintenant elles sont en conflit avec votre build. Ou peut-être qu'il y a un nouveau bug dans la nouvelle version mineure de votre dépendance et vous n'avez aucun problème dans votre code (parce que vous avez installé vos dépendances avant la nouvelle version), mais toute autre personne essayant d'installer et de construire votre projet à partir du référentiel sera confrontée au bug dont vous n'avez même pas connaissance (et vous ne serez pas en mesure de le reproduire sur votre machine).

package-lock.json existe pour résoudre ce problème et pour aider les développeurs à avoir le même ensemble de dépendances à travers le projet. Idéalement, il devrait être livré au dépôt, mais de nombreux développeurs décident d'ajouter ce fichier à .gitignore. Et s'il n'est plus là, vous pouvez vous retrouver avec les problèmes ci-dessus. Il est donc préférable de ne pas faire aveuglément confiance à la résolution de vos dépendances et de la fixer sur la version spécifique, de la scanner régulièrement pour détecter les vulnérabilités (avec npm audit), puis de la mettre à jour et de la tester manuellement.

Conseil 6. Essayez de mettre votre application à niveau vers la nouvelle version d'Angular dès que vous le pouvez.

Angular évolue en permanence et de nouvelles versions sortent tous les 6 mois environ. En gardant votre application à jour, vous pourrez utiliser toutes les nouvelles fonctionnalités, y compris des constructions plus rapides et d'autres optimisations. En outre, la mise à niveau vers la prochaine version majeure d'Angular ne devrait pas poser de gros problèmes dans ce cas. Mais si vous avez 5 versions de retard et que votre application est de taille moyenne ou grande, le processus de mise à jour vers la dernière version peut être difficile car Angular n'a pas de schéma pour mettre à niveau les applications sautant des versions intermédiaires d'Angular. Vous devrez mettre à jour toutes les versions intermédiaires une par une, en vérifiant que l'application fonctionne sur chaque version. La mise à jour directe sans schéma Angular CLI est possible, mais peut aussi être délicate. Je vous suggère donc de garder votre application fraîche et à jour.

Conseil 7. Essayez de réduire votre liste de dépendances

Il est facile de prendre l'habitude d'introduire de nouvelles dépendances dans votre application lorsque vous avez besoin de nouvelles fonctionnalités. Mais avec chaque dépendance, la complexité de votre application augmente et le risque d'une soudaine avalanche de dettes techniques s'accroît.

Si vous décidez d'ajouter une nouvelle dépendance dans votre application, pensez à ceci :

  • La dépendance est-elle bien supportée ?
  • Combien de personnes l'utilisent ?
  • Quelle est la taille de l'équipe de développement ?
  • A quelle vitesse ils ferment les problèmes sur GitHub ?
  • La documentation de la dépendance est-elle bien rédigée ?
  • A quelle vitesse est-elle mise à jour après la sortie d'une nouvelle version d'Angular ?
  • Quel est l'impact de cette dépendance sur les performances et la taille du bundle de votre application ?
  • Quelle sera la difficulté de remplacer cette dépendance si elle est abandonnée ou dépréciée à l'avenir ?

Si la réponse à certaines de ces questions est négative, envisagez de vous en débarrasser ou au moins de la remplacer par quelque chose de plus mature et de mieux supporté.

Conseil 8. N'utilisez pas <any> comme type "temporaire".

Encore une fois, il est facile de commencer à utiliser n'importe quel type au fur et à mesure que vous écrivez votre logique d'entreprise, parce que l'écriture de types appropriés pourrait prendre du temps, et vous devez terminer votre tâche dans ce sprint. Les types peuvent être ajoutés plus tard, bien sûr. Mais c'est une pente glissante pour augmenter la dette technique.

L'architecture de votre application et les types doivent être définis avant d'écrire toute logique métier. Vous devez clairement comprendre quels objets vous aurez et où ils seront utilisés. La spécification avant le code, n'est-ce pas ? (Tom Demarco a écrit un livre à ce sujet avant qu'il ne devienne courant : https://www.amazon.com/Deadline-Novel-About-Project-Management/dp/0932633390).

Si vous écrivez le code sans types prédéfinis, vous risquez de vous retrouver avec une architecture d'application moins bonne et des fonctions qui utilisent des objets très similaires mais différents. Vous devrez donc soit créer des types différents pour chaque fonction (ce qui aggravera encore les choses), soit passer votre temps à écrire des spécifications, des types ET du refactoring, ce qui est une perte de temps par rapport à ce qui aurait été fait auparavant.

Conseil 9. Prenez le temps de comprendre le processus de construction

Angular fait un excellent travail pour faciliter le travail du développeur en ce qui concerne la construction du projet. Mais les options par défaut ne sont pas toujours les meilleures dans tous les cas.

Passez votre temps à comprendre comment le processus de construction fonctionne dans Angular, quelles sont les différences entre les constructions de développement et de production, quelles options Angular a pour les constructions (comme les optimisations, les cartes de source, le regroupement et plus).

Conseil 10. Examinez le contenu de votre liasse.

Toutes les bibliothèques ne fournissent pas de tree-shaking et nous ne faisons pas toujours les importations de la bonne manière, il y a donc toujours une chance que quelque chose de redondant soit empaqueté avec notre application.

C'est donc une bonne habitude d'examiner le contenu de votre bundle de temps en temps.

Il y a de bons articles décrivant le processus en utilisant webpack-bundle-analyzer , donc je ne le couvrirai pas ici, mais voici un lien pour l'un d'entre eux : https://www.digitalocean.com/community/tutorials/angular-angular-webpack-bundle-analyzer

Je couvrirai ce sujet plus en détail plus tard dans la série.

Conseil 11. Utilisez la propriété providedIn des services au lieu d'importer le service dans le module.

De nombreux exemples de code Angular sur Internet utilisent l'importation des services dans les modules. Mais ce n'est pas la façon préférée de déclarer les services depuis Angular 6 ou 7. Nous devrions utiliser la propriété providedIn du décorateur @Injectable pour permettre le tree-shaking et un meilleur bundle de nos applications. Angular est suffisamment intelligent pour comprendre dans quel bundle le service doit être inclus, quand il doit être initialisé et combien d'instances du service doivent être créées.

Il y a trois valeurs que providedIn accepte. La plupart du temps, root est suffisant, mais il en existe deux autres :

  • root : le service sera singleton dans la portée de l'application
  • any : une instance du service sera créée pour tous les modules chargés avec empressement, avec une instance différente créée pour chaque module paresseux.
  • platform : le service sera singleton pour toutes les applications tournant sur la même page.

Conseil 12. N'oubliez pas les principales règles d'exécution

  • Utilisez trackBy pour les collections afin de réduire les opérations de redécoupage et l'exécution de JavaScript.
  • Utilisez la stratégie de détection des changements onPush partout où vous le pouvez (je l'aborderai dans l'article dédié).
  • Effectuez les calculs lourds en dehors de ngZone
  • Utilisez des modèles d'accélération et de ralentissement avec vos événements pour éviter les appels inutiles au serveur et l'inondation d'événements.
  • Utilisez le défilement virtuel pour afficher de grands ensembles de données.
  • Utiliser des pure pipes pour la transformation des données dans vos templates
  • Utilisez la compilation AoT
  • Chargez paresseusement les parties de votre application qui ne sont pas nécessaires à son démarrage.
  • Évitez les calculs et les appels de fonction dans vos modèles.

Merci de votre lecture ! J'espère que certains de ces conseils vous ont été utiles. Si vous avez des commentaires et des remarques, s'il vous plaît, faites-le moi savoir dans les commentaires, je serai heureux de discuter 😃. A bientôt !

0
0 174
Article Sergei Sarkisian · Juil 3, 2022 9m read

Bonjour, je m'appelle Sergei Sarkisian et je crée des fronts Angular depuis plus de 7 ans en travaillant chez InterSystems. Comme Angular est un framework très populaire, nos développeurs, clients et partenaires le choisissent souvent comme partie de la pile pour leurs applications.

J'aimerais commencer une série d'articles qui couvriront différents aspects d'Angular : concepts, comment faire, meilleures pratiques, sujets avancés et plus encore. Cette série s'adressera aux personnes qui connaissent déjà Angular et ne couvrira pas les concepts de base. Comme je suis en train d'établir la feuille de route des articles, je voudrais commencer par mettre en évidence certaines fonctionnalités importantes de la dernière version d'Angular.

Formes strictement typées

Il s'agit probablement de la fonctionnalité d'Angular la plus demandée ces dernières années. Avec Angular 14, les développeurs peuvent désormais utiliser toutes les fonctionnalités de vérification stricte des types de TypeScript avec les formulaires réactifs d'Angular.

La classe FormControl est maintenant générique et prend le type de la valeur qu'elle contient.

/* Avant Angular 14 */
const untypedControl = new FormControl(true);
untypedControl.setValue(100); // est définie, aucune erreur

// Maintenant
const strictlyTypedControl = new FormControl<boolean>(true);
strictlyTypedControl.setValue(100); // vous recevrez le message d'erreur de vérification de type ici

// Également dans Angular 14
const strictlyTypedControl = new FormControl(true);
strictlyTypedControl.setValue(100); // vous recevrez le message d'erreur de vérification de type ici

Comme vous le voyez, le premier et le dernier exemple sont presque identiques, mais les résultats sont différents. Cela se produit parce que dans Angular 14 la nouvelle classe FormControl infère les types à partir de la valeur initiale fournie par le développeur. Ainsi, si la valeur true a été fournie, Angular définit le type boolean | null pour ce FormControl. La valeur nullable est nécessaire pour la méthode .reset() qui annule les valeurs si aucune valeur n'est fournie.

Une ancienne classe FormControl non typée a été convertie en UntypedFormControl (il en est de même pour UntypedFormGroup, UntypedFormArray et UntypedFormBuilder) qui est pratiquement un alias pour FormControl<any>. Si vous effectuez une mise à jour depuis une version précédente d'Angular, toutes les mentions de votre classe FormControl seront remplacées par la classe UntypedFormControl par Angular CLI.

Les classes Untyped* sont utilisées avec des objectifs spécifiques :

  1. Faire en sorte que votre application fonctionne absolument comme elle l'était avant la transition de la version précédente (rappelez-vous que le nouveau FormControl déduira le type de la valeur initiale).
  2. S'assurer que toutes les utilisations de FormControl<any> sont prévues. Donc vous devrez changer tout UntypedFormControl en FormControl<any> par vous-même.
  3. Pour fournir aux développeurs plus de flexibilité (nous couvrirons ceci ci-dessous)

Rappelez-vous que si votre valeur initiale est null alors vous devrez explicitement spécifier le type de FormControl. Aussi, il y a un bug dans TypeScript qui exige de faire la même chose si votre valeur initiale est false.

Pour le groupe de formulaire, vous pouvez aussi définir l'interface et juste passer cette interface comme type pour le FormGroup. Dans ce cas, TypeScript déduira tous les types à l'intérieur du FormGroup.

interface LoginForm {
    email: FormControl<string>;
    password?: FormControl<string>;
}

const login = new FormGroup<LoginForm>({
    email: new FormControl('', {nonNullable: true}),
    password: new FormControl('', {nonNullable: true}),
});

La méthode de FormBuilder .group() a maintenant un attribut générique qui peut accepter votre interface prédéfinie comme dans l'exemple ci-dessus où nous avons créé manuellement FormGroup :

interface LoginForm {
    email: FormControl<string>;
    password?: FormControl<string>;
}

const fb = new FormBuilder();
const login = fb.group<LoginForm>({
    email: '',
    password: '',
});

Comme notre interface n'a que des types primitifs non nuls, elle peut être simplifiée avec la nouvelle propriété nonNullable FormBuilder (qui contient l'instance de la classe NonNullableFormBuilder qui peut aussi être créée directement) :

const fb = new FormBuilder();
const login = fb.nonNullable.group({
    email: '',
    password: '',
})

❗ Notez que si vous utilisez un FormBuilder non Nullable ou si vous définissez une option nonNullable dans le FormControl, alors lorsque vous appelez la méthode .reset(), elle utilisera la valeur initiale du FormControl comme valeur de réinitialisation.

Aussi, il est très important de noter que toutes les propriétés dans this.form.value seront marquées comme optionnelles. Comme ceci :

const fb = new FormBuilder();
const login = fb.nonNullable.group({
    email: '',
    password: '',
});

// login.value
// {
//   email?: string;
//   password?: string;
// }

Cela se produit parce que lorsque vous désactivez un FormControl à l'intérieur du FormGroup, la valeur de ce FormControl sera supprimée de form.value.

const fb = new FormBuilder();
const login = fb.nonNullable.group({
    email: '',
    password: '',
});

login.get('email').disable();
console.log(login.value);

// {
//   password: ''
// }

Pour obtenir l'objet complet du formulaire, vous devez utiliser la méthode .getRawValue() :

const fb = new FormBuilder();
const login = fb.nonNullable.group({
    email: '',
    password: '',
});

login.get('email').disable();
console.log(login.getRawValue());

// {
//   email: '',
//   password: ''
// }

Avantages des formulaires strictement dactylographiés :

  1. Toute propriété et méthode retournant les valeurs du FormControl / FormGroup est maintenant strictement typée. Par exemple, value, getRawValue(), valueChanges.
  2. Toute méthode permettant de modifier la valeur d'un FormControl est maintenant sécurisée par le type : setValue(), patchValue(), updateValue().
  3. Les FormControls sont maintenant strictement typés. Cela s'applique également à la méthode .get() de FormGroup. Cela vous empêchera également d'accéder aux FormControls qui n'existent pas au moment de la compilation.

Nouvelle classe FormRecord

L'inconvénient de la nouvelle classe FormGroup est qu'elle a perdu sa nature dynamique. Une fois définie, vous ne serez pas en mesure d'ajouter ou de supprimer des FormControls à la volée.

Pour résoudre ce problème, Angular présente une nouvelle classe - FormRecord. FormRecord est pratiquement le même que FormGroup, mais il est dynamique et tous ses FormControls doivent avoir le même type.

folders: new FormRecord({
  home: new FormControl(true, { nonNullable: true }),
  music: new FormControl(false, { nonNullable: true })
});

// Ajouter un nouveau FormContol au groupe
this.foldersForm.get('folders').addControl('videos', new FormControl(false, { nonNullable: true }));

// Cela entraînera une erreur de compilation car le contrôle est de type différent.
this.foldersForm.get('folders').addControl('books', new FormControl('Some string', { nonNullable: true }));

Et comme vous le voyez, ceci a une autre limitation - tous les FormControls doivent être du même type. Si vous avez vraiment besoin d'un FormGroup à la fois dynamique et hétérogène, vous devriez utiliser la classe UntypedFormGroup pour définir votre formulaire.

Composants sans module (autonomes)

Cette fonctionnalité est toujours considérée comme expérimentale, mais elle est intéressante. Elle vous permet de définir des composants, des directives et des tuyaux sans les inclure dans un module.

Le concept n'est pas encore totalement au point, mais nous sommes déjà capables de construire une application sans ngModules.

Pour définir un composant autonome, vous devez utiliser la nouvelle propriété standalone dans le décorateur Composant/Pipe/Directive :

@Component({
  selector: 'app-table',
  standalone: true,
  templateUrl: './table.component.html'
})
export class TableComponent {
}

Dans ce cas, ce composant ne peut être déclaré dans aucun NgModule. Mais il peut être importé dans les NgModules et dans d'autres composants autonomes.

Chaque autonome composant/pipe/directive a maintenant un mécanisme pour importer ses dépendances directement dans le décorateur :

@Component({
  standalone: true,
  selector: 'photo-gallery',
  // un module existant est importé directement dans un composant autonome
	// CommonModule importé directement pour utiliser les directives Angular standard comme *ngIf
  // le composant autonome déclaré ci-dessus est également importé directement
  imports: [CommonModule, MatButtonModule, TableComponent],
  template: `
    ...
    <button mat-button>Next Page</button>
		<app-table *ngIf="expression"></app-table>
  `,
})
export class PhotoGalleryComponent {
}

Comme je l'ai mentionné ci-dessus, vous pouvez importer des composants autonomes dans n'importe quel ngModule existant. Il n'est plus nécessaire d'importer l'intégralité d'un module partagé, nous ne pouvons importer que les éléments dont nous avons réellement besoin. C'est également une bonne stratégie pour commencer à utiliser de nouveaux composants autonomes:

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, HttpClientModule, TableComponent], // import our standalone TableComponent
  bootstrap: [AppComponent]
})
export class AppModule {}

Vous pouvez créer un composant autonome avec Angular CLI en tapant:

ng g component --standalone user

Application Bootstrap sans module

Si vous voulez vous débarrasser de tous les ngModules dans votre application, vous devrez amorcer votre application différemment. Angular a une nouvelle fonction pour cela que vous devez appeler dans le fichier main.ts:

bootstrapApplication(AppComponent);

Le second paramètre de cette fonction vous permettra de définir les providers dont vous avez besoin dans votre application. Comme la plupart des fournisseurs existent généralement dans les modules, Angular (pour l'instant) exige d'utiliser une nouvelle fonction d'extraction importProvidersFrom pour eux :

bootstrapApplication(AppComponent, { providers: [importProvidersFrom(HttpClientModule)] });

Chargement paresseux de la route des composants autonomes:

Angular dispose d'une nouvelle fonction de route de chargement paresseux, loadComponent, qui existe exactement pour charger des composants autonomes:

{
  path: 'home',
  loadComponent: () => import('./home/home.component').then(m => m.HomeComponent)
}

loadChildren ne vous permet plus seulement de charger paresseusement un ngModule, mais aussi de charger les routes des enfants directement à partir du fichier des routes :

{
  path: 'home',
  loadChildren: () => import('./home/home.routes').then(c => c.HomeRoutes)
}

Quelques notes au moment de la rédaction de l'article

  • La fonctionnalité des composants autonomes est encore au stade expérimental. Elle sera bien meilleure à l'avenir avec le passage à Vite builder au lieu de Webpack, un meilleur outillage, des temps de construction plus rapides, une architecture d'application plus robuste, des tests plus faciles et plus encore. Mais pour l'instant, beaucoup de ces éléments sont manquants, nous n'avons donc pas reçu le paquet complet, mais au moins nous pouvons commencer à développer nos applications avec le nouveau paradigme Angular en tête.
  • Les IDE et les outils Angular ne sont pas encore tout à fait prêts à analyser statiquement les nouvelles entités autonomes. Comme vous devez importer toutes les dépendances dans chaque entité autonome, si vous manquez quelque chose, le compilateur peut aussi le manquer et vous faire échouer au moment de l'exécution. Cela s'améliorera avec le temps, mais pour l'instant, les développeurs doivent accorder plus d'attention aux importations.
  • Il n'y a pas d'importations globales présentées dans Angular pour le moment (comme cela se fait dans Vue, par exemple), donc vous devez importer absolument chaque dépendance dans chaque entité autonome. J'espère que ce problème sera résolu dans une prochaine version, car l'objectif principal de cette fonctionnalité est de réduire le boilerplate et de rendre les choses plus faciles.

C'est tout pour aujourd'hui. A bientôt !

0
0 424
Annonce Robert Bira · Juin 13, 2022

 Un webinaire a été organisé le mardi 8 juin pour vous faire découvrir l'usage de Python dans InterSystems IRIS ® et InterSystems IRIS for Health™ version 2022.1.

Dans cette présentation technique, nous détaillons l'étendue du support dont bénéficient les développeurs Python™ en utilisant la plateforme de gestion de données InterSystems IRIS®, notamment :

0
0 54
Annonce Irène Mykhailova · Juin 6, 2022

Nous serons au Global Summit en juin ! Si vous prévoyez d'y assister, venez nous dire bonjour dans le pavillon des partenaires. Juste un avertissement, notre marque peut sembler un peu différente de ce à quoi vous êtes habitué 👀

Nous sommes impatients de rencontrer tout le monde et d'entendre ce que vous avez fait depuis 2019. Si vous souhaitez réserver une réunion ou rejoindre notre session de groupe d'utilisateurs, envoyez un e-mail à laurelj@georgejames.com. Nous espérons vous voir à Seattle !

 

0
0 54
Annonce Robert Bira · Mai 17, 2022

Cette première journée se termine et nous tenions à remercier nos visiteurs, nos collaborateurs et nos partenaires MyPLGuerbetSynodisNéoCALYPS Data Intelligence et Amazon Web Services (AWS) pour leur présence !  

RDV demain à 15h15 pour une agora exclusive en présence de Guillaume Rongier, notre évangéliste technologique, d'Etienne Prothon, Architecte Cloud chez MyPL et Patrick Lamplé, Principal Specialist Solutions Architect, Healthcare & Life Sciences, Amazon Web Services (AWS) pour partager un REX d'une implémentation FHIR dans le Cloud. 
A demain 

0
0 30
Annonce Irène Mykhailova · Mai 8, 2022

Nous avons publié 6 pages Angular pour tous les utilisateurs de leur phase de test bêta :

Transition, Create, Clone, Merge, Standard Changes et Peer Review Docs.

Tout problème ou commentaire peut être signalé ici ou via vos canaux d'assistance habituels. Les utilisateurs non bêta peuvent basculer leur statut bêta ici dans l'application CCR.

0
0 71
Article Sylvain Guilbaud · Avr 19, 2022 2m read

Kong fournit en open source un outil de gestion de ses configurations (écrit en Go), appelé decK (pour declarative Kong)

  • Vérifiez que decK reconnaît votre installation Kong Gateway via deck ping
deck ping   
Successfully connected to Kong!
Kong version:  2.3.3.2-enterprise-edition
  • Exporter la configuration de Kong Gateway dans un fichier "kong.yaml" via deck dump
deck dump
  • Après avoir modifié le kong.yaml, afficher les différences via deck diff
0
0 182
Article Irène Mykhailova · Mars 25, 2022 2m read

image

Salut les développeurs,

Nous sommes au Hacking Health Camp 2022 à Strasbourg et ce durant tout le week-end.

Toute l'équipe de modération est sur place @Irène Mykhailova, @Guillaume Rongier, @Lorenzo Scalese : image

Et on s'éclate ! image

Nous vous tiendrons informé tout au long de la journée du déroulement de cet évènement.

Pour rappel, vous trouverez ici notre site dédié au hackathon : https://hackinghealth-2022.isccloud.io/

MIS A JOUR 13:00 Donc, la première partie des conférences est terminée et il est temps d'aller explorer les lieux

image

et de prendre une photo des équipes InterSystems qui se mobilisent tout le weekend : image

Nous attendons la présentation de David Hancock sur le sujet IMPROVING YOUR HEALTH SYSTEM OUTCOMES BY IMPROVING YOUR DIGITAL HEALTH SYSTEMS après cette pause déjeuner.

MIS A JOUR 18:00 David a sensibilisé et motivé les troupes sur l'importance de l'interop. image

image

IMG_20220325_234205

La conférence est terminée, les coaches se sont réunis (comme les Avengers ;) ) et on attend avec impatience les pitchs des projets. IMG_20220325_234317

image

IMG_20220326_133508

MIS A JOUR 21:00 @Guillaume Rongier a mis le feu avec son intro FHIR IMG_20220325_184205

Les groupes se forment, 1 coeur = 1 projet et c'est parti pour 50h de folie créative et collaborative image

image

Et c'est tout pour aujourd'hui. A demain!

4
0 2101
Article Irène Mykhailova · Mars 27, 2022 2m read

HHC-banner

Salut les développeurs !

Le dernier jour du Hacking Health Camp 2022 à Strasbourg, France, approche à grands pas et aujourd'hui nous verrons toutes les merveilleuses créations des équipes. Ils ont travaillé toute la nuit et nos équipes sur site et en ligne ont travaillé avec eux et ont répondu à leurs questions.

IMG_20220327_103941

Nos coachs se sont reuni plus tard dans la matinée pour discuter et échanger les nouvelles.

IMG_20220327_105236

MIS A JOUR 16:00:

Les équipes ont terminé leurs présentations et le jury délibère.

image

image

MIS A JOUR 19:00:

Les prix ont été décernés. InterSystems a décerné son prix (un emplacement de stand au salon SANTEXPO du 17 au 19 mai 2022, Paris et 6 mois de XSmall (1 500 demandes par minute) ou 3 mois de Small (4 500 demandes par minute) d’accès gratuit au service cloud FHIR InterSystems) au projet Néo. @Laurent Viquesnel a remis le prix.

image

Bien sûr, après la fin de la partie officielle, notre équipe s'est réunie à l'extérieur pour célébrer la conclusion de l'événement.

image

Et nous avons encore une fois félicité l'équipe qui a remporté notre prix !

image

C'est la conclusion de cette incroyable expérience de 3 jours ! Nous reviendrons l'année prochaine pour voir d'autres équipes formidables et des projets intéressants !

1
0 86
Article Irène Mykhailova · Mars 26, 2022 2m read

image

Salut les développeurs,

En forme pour cette 2e journée en direct du Hacking Health Camp 2022

Tous nos coachs @Irène Mykhailova, @Lorenzo Scalese, @Laurent Viquesnel et @Guillaume Rongier sont mobilisés ce matin pour échanger avec l'ensemble des projets. 30 min par équipe pour les guider au mieux.

Et biensûr répondre à leurs questions sur FHIR

En travaillant en groupes, nos coachs ont fait remarquer les projets qui pourraient bénéficier de l'utilisation de FHIR et ont pris des "rendez-vous" avec les équipes pour les aider à utiliser FHIR dans leurs logiciels.

MIS A JOUR 15:00

@Guillaume Rongier a présenté une démo. Et on espère que cela aidera les équipes à inclure notre solution d'intégration dans leurs projets !

IMG_2697

Et pour clarifier des questions restantes, il y a des séances individuelles avec les équipes.

image

MIS A JOUR 18:00

Comme vous pouvez le constater, la première partie de la journée a été consacrée aux pitchs et à les discussions des projets en général. Après une pause déjeuner, le vrai travail a commencé ! Les gens bossent sur le front-end, le back-end, la présentation, les points légaux etc. Et pour leur faciliter la vie, nos coachs aident les équipes qui utilisent FHIR à surmonter les difficultés qu'elles peuvent rencontrer.

image

image

Et certains discutent des projets avec leurs collègues coachs.

image

Quoi qu'il en soit, tout le monde carbure. Même notre support extérieur (@Dmitry Maslennikov et @José Pereira), qui aide les équipes jour et nuit via Discord, n'import où ils sont basées géographiquement.

Et pendant une petite accalmie dans le travail, @Guillaume Rongier a trouvé le temps de faire une interview et de parler encore plus du FHIR.

<iframe width="560" height="315" src="https://www.youtube.com/embed/1r-s_N_vlg0?start=5628" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

MIS A JOUR 23:00

Nous continuons à aider les équipes à atteindre tout leur potentiel :)

image

image

OK, c'est tout pour ce soir ! A demain pour decouvrir les prototypes !

1
0 113
Article Irène Mykhailova · Mars 22, 2022 3m read

Notre engagement

Dans l'intérêt de favoriser un environnement ouvert et accueillant, nous, en tant que contributeurs et gestionnaires, nous nous engageons à garantir que la participation à la communauté des développeurs d'InterSystems soit une expérience sans harcèlement pour tous, indépendamment de l'âge, de la taille, du handicap, de l'appartenance ethnique, de l’expression sexuelle, du niveau d'expérience, de la nationalité, de l'apparence personnelle, de la race, de la religion ou de l'identité et orientation sexuelles.

Nos règles

Exemples de comportements qui contribuent à créer un environnement positif :

  • Utiliser un langage accueillant et inclusif
  • Être respectueux des différents points de vue et expériences vécues
  • Accepter poliment les critiques constructives
  • Se concentrer sur ce qui est le mieux pour la communauté
  • Faire preuve d’empathie envers les autres membres de la communauté

Exemples de comportements non acceptables :

  • Utilisation d'un langage ou d'images à caractère sexuel et des avances ou attentions sexuelles non sollicitées
  • Commentaires insultants/désobligeants (troll) et attaques personnelles ou politiques
  • Harcèlement public ou privé
  • Publication d'informations privées d'autrui, telles qu'une adresse physique ou électronique, sans autorisation explicite
  • Toute autre conduite qui pourrait raisonnablement être considérée comme inappropriée dans un cadre professionnel
  • Nous acceptons toutes les réclamations et évaluations concernant le comportement et les fonctionnalités des plateformes de données d'InterSystems, mais nous n'acceptons pas et ne discutons pas le comportement et le niveau de service des départements et des employés d'InterSystems.
  • Nous nous réservons le droit de supprimer toute publication (sans en donner la raison) qui, selon nous, ne fournit pas d'informations utiles aux membres de la communauté.
  • Nous nous réservons le droit de restreindre l'accès à la communauté (sans donner de raison) aux personnes dont les publications ont été supprimées plusieurs fois.

Nos responsabilités

Les responsables de projet doivent clarifier les critères de comportement acceptables et prendre des mesures correctives appropriées et équitables en réponse à tout cas de comportement inacceptable.

Les responsables de projet ont le droit et la responsabilité de supprimer, modifier ou rejeter les commentaires, les commits, le code, les modifications de wiki, les problèmes et autres contributions qui ne sont pas conformes au présent code de conduite, ou de bannir temporairement ou définitivement tout contributeur pour d'autres comportements qu'ils jugent inappropriés, menaçants, offensants ou nuisibles.

Portée

Le présent code de conduite s'applique à toute contribution publique à la communauté des développeurs d'InterSystems, qui peut se trouver sur community.intersystems.com, es.community.intersystems.com et openexchange.intersystems.com. La représentation de la communauté peut être définie et précisée par les responsables de la communauté InterSystems.

Application

Les cas de comportement abusif, de harcèlement ou tout autre comportement inacceptable peuvent être signalés en contactant l'équipe du projet à support@intersystems.com. Toutes les plaintes seront examinées et étudiées par l'équipe de la communauté et se traduiront par une réponse appropriée aux circonstances. L’équipe de la communauté est tenue de respecter la confidentialité à l'égard de la personne qui remonte un incident. Plus de détails sur la politique de mise en application des règles peuvent être publiés séparément.

Les membres de la communauté des développeurs d'InterSystems qui ne respectent pas ou n'appliquent pas le code de conduite de bonne foi peuvent subir des répercussions temporaires ou permanentes, comme déterminées par les autres membres responsables de la communauté.

Attribution

Ce code de conduite est adapté du Contributor Covenant, version 1.4, disponible sur http://contributor-covenant.org/version/1/4

0
0 88