Denne guide har til formål at give anvendere et overblik af NAP SDK'et.
Anvendere er primært projektudviklere, hvilket betyder at denne guide er anvendt til dem.
På baggrund af følgende eksempler, er det muligt at komme hurtigt i gang med anvendelsen af SDK'erne.
Nap-typescript-sdk er det basale SDK. Det udstiller en række metoder og interfaces som vil blive beskrevet i følgende:
En wrapper af kontekstbroen.
export interface NAP { fromHost$: Observable<NAPMessage>; toHost$: Subject<NAPMessage>; errors$: Observable<NAPError>; subscribe: (subscriber: NAPHostSubscriber) => void; unsubscribe: (subscriber: NAPHostSubscriber) => void; send: (message: NAPMessage) => void; } |
fromHost$: Beskeder af NAPMessages fra værtssystemet. Udstillet som en Observable.
toHost$: Send en NAPMessage til hosten. Denne er udstillet som et subject, som man kan skubbe beskeder til med next().
errors$: SDK fejl, udstillet som en Observable.
subscribe: Subscriber til NAPMessages fra værtsystemet. Det fungere på samme måde som med `fromHost$`, bare uden brug af observables.
unsubscribe: Unsubscribe af NAPMessages fra værtssystemet.
send: Send en NAPMessage - Det fungerer på samme måde som to `toHost$`, bare uden brug af observables.
Består af følgende felter, hvor context propertien, er meget inspireret af FHIR / FHIRcast (https://fhircast.org/specification/Feb2020Ballot/),
export interface NAPMessage { date: string; id: string; event: NAPEvent; } export interface NAPEvent { type: NAPEventType; context?: FHIR.Context[]; } |
Eventkataloget definerer de eventtyper, der kan sendes over NAP i en given version.
Dette eventkatalog lægger sig op af FHIR / FHIRcast, hvilket betyder at eventet har følgende struktur:
Eventkatalog version 1 | |
NAPEventType | Funktionelle beskrivelse |
---|---|
SessionOpen | Start en trusted session hvor brugerens SAMLassertion overføres |
SessionClose | Hvis en bruger ønskes lukkes ud. Alt state skal slettes på web-applikationen |
PatientOpen | Den brugervalgte patient journal. |
PatientClose | Den brugervalgte patient journal lukkes. |
SessionError | Hvis der sker en uventet fejl i gæstesystemet skal dette sendes til værtssystemet og vice versa. |
import { NAPEventCatalogue } from 'nap-typescript-sdk'; const sessionCloseEvent = NAPEventCatalogue.v1.SessionClose; |
Nap-typescript-sdk indeholder derudover en række hjælpefunktioner, som kan være brugbare til at hente værdier eller undgå stavefejl, når der skal laves NAPMessages.
Funktioner, som gør det lettere at hente FHIR specifikke værdier ud af en NAPMessage. Disse kan bruges ved at importere namespacet FHIRValueGetter.
Følgende eksempel mapper en NAPMessage til en SAMLassertion og PatientInfo.
import { FHIRValueGetter, NAPMessage, NAPPatientInfo } from 'nap-typescript-sdk'; const sessionToken = FHIRValueGetter.getSessionValue(napMessage); const patientData: NAPPatientInfo = FHIRValueGetter.getSessionValue(napMessage); |
Enums som gør det nemmere at lave NAPMessages indholdende data.
Følgende er et eksempel hvordan der sendes en fejlbesked.
import {NAPMessage, NAPEventCatalogue, FHIRValueSetter} from 'nap-typescript-sdk'; import { v4 as UUID } from 'uuid'; const napMessageSessionError: NAPMessage = { date: new Date().toISOString(), id: UUID(), event: { type: NAPEventCatalogue.v1.SessionError, context: [ { resource: { resourceType: FHIRValueSetter.FHIRResourceType.Basic, code: { coding: [ { code: NAPEventCatalogue.v1.SessionError, system: FHIRValueSetter.FHIRSystem.NAP, }, ], }, identifier: [ { system: FHIRValueSetter.FHIRIdentifierSystem.NAPErrorMessage, value: 'This is my error message', }, { system: FHIRValueSetter.FHIRIdentifierSystem.NAPErrorDescription, value: 'This is a longere description of the error message', }, ], }, }, ], }, }; NapTypescriptSdk.send(napMessageSessionError) |
Hvis du ønsker at bruge Angular som udviklingsværktøj. SDK'et sørger for at håndtere Angulars change detection zone.
Da nap-angular-sdk er en angular specifik wrapper af nap-typescript-sdk, har den en "peer dependency" hertil.
Følgende eksempel sender en Session-Open besked og får en SAMLassertion tilbage:
import { NapAngularService } from 'nap-angular-sdk'; import { filterEvents, NAPEventCatalogue, NAPMessage } from 'nap-typescript-sdk'; import { v4 as UUID } from 'uuid'; import { NapAngularService } from 'nap-angular-sdk'; import { filterEvents, NAPEventCatalogue, NAPMessage } from 'nap-typescript-sdk'; import { shareReplay } from 'rxjs/operators'; import { v4 as UUID } from 'uuid'; export class MyComponent { // proxy for SAMLAssertion public session$: Observable<NAPMessage | undefined> = this.napSDK.incomming$.pipe( filterEvents([NAPEventCatalogue.v1.SessionOpen, NAPEventCatalogue.v1.SessionClose]) ); constructor(private napSK: NapAngularService) { //Construct an SessionOpen NAPMessage const napMsg: NAPMessage = { date: new Date().toISOString(), id: UUID(), event: { type: NAPEventCatalogue.v1.SessionOpen }, }; // Ask for the SAMLassertion in host this.napSDK.sendMessage(napMsg); } } |
Fuld implementation af eventkataloget ses i nap-reference-web her https://svn.nspop.dk/svn/components/nap/nap-reference-web/trunk/.
Hvis du ønsker at bruge React som udviklingsværktøj. SDK'et sørger for håndtering af state.
Da nap-react-sdk er en react specifik wrapper af nap-typescript-sdk, har den en "peer dependency" hertil.
Følgende eksempel viser hvordan man kan anvende nap-react-sdk til at vise og sende beskeder:
import { NapContextProvider, NAPEventType, useNap } from 'nap-react-sdk'; import React from 'react'; import { v4 as UUID } from 'uuid'; const IncommingMessageComponent: React.FC = () => { const napContext = useNap() return <div> {JSON.stringify(napContext.latestIncomming)}</div> } const IncommingErrorsComponent: React.FC = () => { const napContext = useNap() return ( <div > <p> Error received: {JSON.stringify(napContext.latestError)}</p> </div> ) } const PostMessageComponent: React.FC = () => { const napContext = useNap() return ( <button onClick={() => { napContext.postMessage({ date: new Date().toString(), id: '123', event: { type: NAPEventType.SessionOpen } }) }} > Send message </button> ) } const App = () => { return ( <> <NapContextProvider> <IncommingMessageComponent></IncommingMessageComponent> <IncommingErrorsComponent></IncommingErrorsComponent> <PostMessageComponent></PostMessageComponent> </NapContextProvider> </> ) } export default App |