Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Navitabs
rootSDK'er (NAP) - Leverancebeskrivelse
includeroottrue

Table of Contents

Introduktion

Formål

Denne guide har til formål at give anvendere et overblik af NAP SDK'et, dets indhold og dets anvendelse.

Anvendere af NAP-SDK er primært projektudviklere, hvilket betyder at denne guide er egnet til dem.

Der foreligger desuden anvendelseseksempler. På baggrund af følgende eksempler, er det muligt at komme hurtigt i gang med anvendelsen af SDK'erne. 

Sammenhæng med øvrige dokumenter

Dette dokument er en del af den samlede dokumentation for NAP SDK.

Dokumentet er udformet, så det i videst muligt omfang opfylder sit formål uafhængigt af de øvrige dokumenter.

Ønskes mere information omkring arkitektur og design findes dette på NAP SDK - Design og Arkitektur beskrivelse.

Ønskes mere information omkring installationsvejledning til anvendere findes dette på NAP SDK - Installationsvejledning.

Nap-typescript-sdk

Nap-typescript-sdk er det basale SDK. Det udstiller en række metoder og interfaces som bliver beskrevet nedenfor. 

  • Et NAP interface, som fungerer som en wrapper omkring NAP bridge (NAP SDK - Design og Arkitektur beskrivelse).
  • Et NAP message interface, som er modellen alle beskeder, som kan sendes over NAP. Disse beskeder er meget inspireret af FHIRcast.
  • Et NAPEventCatalogue, der definerer events inspireret af FHIRCast
  • Hjælpemetoder til at sende og formatere beskeder.

NAP interface

En wrapper af NAP Bridge, som et værtssystem ligger på global scope af den embeddede browser. 


Warning
NAP projektet er ikke aktivt og NAP er derfor ikke pt. under support og vedligehold.
NAP er ikke opdateret til at understøtte MitID/NemLogin3 og det er derfor ikke længere
muligt at anvende den nuværende version på testmiljøerne.
En evt. genoptagelse af NAP projektet vil afhænge af konkret efterspørgsel.
Kontakt evt. Sundhedsdatastyrelsen ved interesse i NAP.

Table of Contents

Introduktion

Formål

Denne guide har til formål at give anvendere et overblik af NAP SDK'et, dets indhold og dets anvendelse.

Anvendere af NAP-SDK er primært projektudviklere, hvilket betyder at denne guide er egnet til dem.

Der foreligger desuden anvendelseseksempler. På baggrund af følgende eksempler, er det muligt at komme hurtigt i gang med anvendelsen af SDK'erne. 

Sammenhæng med øvrige dokumenter

Dette dokument er en del af den samlede dokumentation for NAP SDK.

Dokumentet er udformet, så det i videst muligt omfang opfylder sit formål uafhængigt af de øvrige dokumenter.

Ønskes mere information omkring arkitektur og design findes dette på NAP SDK - Design og Arkitektur beskrivelse.

Ønskes mere information omkring installationsvejledning til anvendere findes dette på NAP SDK - Installationsvejledning.

Nap-typescript-sdk

Nap-typescript-sdk er det basale SDK. Det udstiller en række metoder og interfaces som bliver beskrevet nedenfor. 

  • Et NAP interface, som fungerer som en wrapper omkring NAP bridge (NAP SDK - Design og Arkitektur beskrivelse).
  • Et NAP message interface, som er modellen for alle beskeder, som kan sendes over NAP. Disse beskeder er meget inspireret af FHIRcast.
  • Et NAPEventCatalogue, der definerer events inspireret af FHIRCast
  • Hjælpemetoder til at sende og formatere beskeder.


NAP interface

En wrapper af NAP Bridge, som et værtssystem ligger på global scope af den embeddede browser. 

Code Block
languagejs
export interface NAP 
Code Block
languagejs
export interface NAP {
	fromHost$: Observable<NAPMessage>;
	toHost$: Subject<NAPMessage>;
	errors$: Observable<NAPError>;
	subscribe: (subscriber: NAPHostSubscriber) => void; 
	unsubscribe: (subscriber: NAPHostSubscriber) => void; 
	send: (message: NAPMessage) => void;
}

...

Code Block
languagejs
import { createNAP, NAP} from "nap-typescript-sdk";
const nap:NapNAP = createNAP();


NAPMessage

Den grundlæggende model for nap beskeder, der kører over (fromHost$, toHost$, subscribe og send).

...

Code Block
languagejs
export interface NAPMessage {
  date: string;
  id: string;
  event: NAPEvent;
}
export interface NAPEvent {
  type: NAPEventType;
  context?: FHIR.Context[];
}
export interface Context {
    resource?: {
        resourceType: string;
        meta?: Meta;
        code?: {
            coding: Coding[];
        };
        name?: Name[];
        identifier?: Identifier[];
        extension?: Extension[];
    };
}
export interface Name {
    family: string;
    given: string[];
}
export interface Extension {
    url: string;
    valuevalueString?: string;
}
export  interface Identifier  valueBoolean?: boolean;
    valueDate?: Date;
    valueStringArray?: string[];
}
export interface Identifier {
    system: string;
    value: string;
}
export interface Coding {
    system: string;
    code: string;
}
export interface Meta {
    profile: string[];
}

Eventkataloget definerer de eventtyper, der kan sendes over NAP i en given version.

Der er fortaget foretaget en minimal implementation af FHIR for at kunne opfylde nedenstående eventkatalog.

...

I tilfældet af en besked ikke opfylder dataformatet sendes en fejlbesked på error$ (stream med error beskeder), som de indlejrede system kan lytte på.
Se nedenfor, hvordan denne error stream kan anvendes.


Eventkatalog

Dette eventkatalog lægger sig op af FHIR / FHIRcast. Der forekommer en naturlig udvidelse af FHIR / FHIRcast standarden i form af de events der kommunikerer selektion/retrieve/filtering af NAPProjekter.

Eventkatalog version 1

NAPEventTypeFunktionelle beskrivelse
WebAppSelected

Eventkatalog version 1

NAPEventTypeFunktionelle beskrivelse
SessionOpenStart en trusted session hvor brugerens SAMLassertion overføres
SessionCloseHvis en bruger ønskes lukkes ud. Alt state skal slettes på web-applikationen
WebAppOpenSendes udelukkende fra lobbyen. Anvendes når en bruger vælger en afprøvningsløsning i lobbyen
PatientOpenDen brugervalgte patient journal.
PatientCloseDen brugervalgte patient journal lukkes.
ProjectsRetrievedSendes udelukkende fra lobbyen. Anvendes når projekter er hentet. Giver hosten en mulighed for at sortere i visning af projekter
ProjectsFilteredAnvendes udelukkende i Lobbyen. Anvendes til at filtrere i de projekter der vises.

SessionClose 

Hvis en bruger ønskes logget ud. Alt state skal slettes på web-applikationen.

PatientOpenDen brugervalgte patient journal.
PatientCloseDen brugervalgte patient journal lukkes.
SessionErrorHvis der sker en uventet fejl i sessionen (http errors / fejl i dataformatet eller lignende) sendes dette til værtssystemet og vice versa.
MessageFactory

Factory metoder til at kreere NAPMessages.

createPatientOpenMessage:

(uuid:

string,

givenName?:

string[],

familyName?:

string,

ssNo?:

string)

=>

NAPMessage,
createPatientCloseMessage:

(uuid:

string,

givenName?:

string[],

familyName?:

string,

ssNo?:

string)

=>

NAPMessage,

createSessionOpenMessage

createProjectsRetrievedMessage:

(uuid:

string)

string, projectShortNames: string[]) =>

NAPMessage,
createSessionCloseMessage:

(uuid:

string)

=>

NAPMessage,
createSessionErrorMessage:

(uuid:

string,

errorMessage:

string,

errorDescription:

string)

=>

NAPMessage

Som i FHIRCast definerer eventtypen dataformatet. Eksempler på disse events er illustreret nedenfor.

Dog er WebAppOpen ikke beskrevet i dette dokument, da dette event er tilegnet kommunikation lobby-værtssytem. Du kan finde mere information om dette event på NAP Platform - Guide til anvendere.

Eksempel på at anvendelse af eventkatalog version 1: 

Code Block
languagejs
import { NAPEventCatalogue } from 'nap-typescript-sdk';
const sessionCloseEvent = NAPEventCatalogue.v1.SessionClose;

NAPError

Model for de SDK fejl. Disse beskeder sendes, hvis sker der fejl i createNAP() kaldet -  når NAP bridge skal wrappes eller når en besked ikke overholder dataformatet.

Code Block
languagejs
export interface NAPError {
  id: number;
  message: string;
  isFatal: boolean;
}

Eksempel på brug af errors$

Fejl bliver således skrevet i web konsollen.

,
createWebAppSelectedMessage: (
uuid: string,
webAppUrl: string,
webAppProducer: string,
webAppReleaseDate: Date,
webAppShortName: string,
webAppServiceEntry: string,
webAppCatalogueVersion: string[],
webAppAudience?: string) => NAPMessage
}

Som i FHIRCast definerer eventtypen dataformatet. Eksempler på disse events er illustreret nedenfor.

Dog er WebAppSelected, ProjectsRetrieved og ProjectsFiltered  ikke beskrevet i dette dokument, da disse events er tilegnet kommunikation mellem lobby og værtssystem. Du kan finde mere information om disse events på NAP Platform - Guide til anvendere.

Eksempel på anvendelse af eventkatalog version 1: 

Code Block
languagejs
import { NAPEventCatalogue } from 'nap-typescript-sdk';
const sessionCloseEvent = NAPEventCatalogue.v1.SessionClose;

NAPError

Interface for SDK fejl. Disse beskeder emittes af errors$ i tilfælde af initialiseringsfejl, hvis sker der fejl i createNAP() kaldet når NAP bridge skal wrappes, eller i tilfælde ar marshalling fejl, hvis en besked ikke overholder dataformatet. Se evt. NAPMessage Dataformat ovenfor. 

Code Block
languagejs
export interface NAPError {
  id: number;
  message: string;
  isFatal: boolean;
}

Eksempel på brug af errors$

Fejl bliver således skrevet i web konsollen.

Code Block
languagejs
this.
Code Block
languagejs
this.napAngular.errors$.subscribe(res => {
     console.error(res);
    });

...

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 og generere NAPMessages.

Komplet liste over hjælpefunktioner:

getPatientInfo(napMessage: NAPMessage): NAPPatientInfo | undefined
Funktion

getSessionValue(napMessage: NAPMessage): string | undefined

Henter samlAssertion. Returnerer undefined, hvis ikke data kan formateres.

Henter patientinfo. Returnerer undefined, hvis ikke data kan formateres.
filterEvents(type: string[]): Observable<NAPMessage>Filtrer på et array eventtypes. Returnerer en observable, der kun emitter, når et event med en af de angivne typer emittes fra source.

filterEvent(type: string): Observable<NAPMessage>

Filtrer på en event. Returnerer en observable, der kun emitter, når et event med en den angivne type emittes fra source.

...


nap-message-factory


createBasicNapMessage = (uuid: string, type: NAPEventType): NAPMessage

Laver en basal NAPMessage med det NAPEventType og ID som er angivet. Beskeden har ingen context.

createPatientOpenMessageV1 = (uuid: string, givenName?: string[], familyName?: string, ssNo?: string): NAPMessage

Laver en patientOpen NAPMessage med de patientinformationer og det ID, som er angivet.

createPatientCloseMessageV1 = (uuid: string, givenName?: string[], familyName?: string, ssNo?: string): NAPMessage

Laver en patientClose NAPMessage med de patientinformationer og det ID der er angivet.

createSessionCloseMessageV1 = (uuid: string): NAPMessage

Laver en sessionClose NAPmessage med det ID der er angivet.

createProjectsRetrievedMessageV1 = (uuid: string, webAppShortNames: string[]): NAPMessage

Anvendes kun i nap-lobby. Laver en NAPMessage med de Projekter, som er tilgængelig.

createSessionErrorMessageV1 = (uuid: string, errorMessage: string, errorDescription: string): NAPMessage

Laver en sessionError NAPMessage med det ID og de fejl beskrivelser, som er angivet.

createWebAppSelectedMessageV1 = (
uuid: string,
webAppUrl: string,
webAppProducer: string,
webAppReleaseDate: Date,
webAppServiceEntry: string,
webAppShortName: string,
webAppCatalogueVersion: string[],
webAppAudience?: string): NAPMessage

Anvendes kun i nap-lobby. Laver en WebAppSelectedNAPMessage med de WebApp detaljer der er angivet.
FHIRValueGetter

getFilteredProjects(napMessage: NAPMessage): string[] | undefined

Anvendes kun i nap-lobby. Henter en filtreret liste af projekter der ønskes vist i lobbyen

getPatientInfo(napMessage: NAPMessage): NAPPatientInfo | undefinedHenter patientinfo. Returnerer undefined, hvis ikke data kan formateres.
filterEvents
filterEvents(type: string[]): Observable<NAPMessage>Filtrer på et array eventtypes. Returnerer en observable, der kun emitter, når et event med en af de angivne typer emittes fra source.

filterEvent(type: string): Observable<NAPMessage>

Filtrer på en event. Returnerer en observable, der kun emitter, når et event med en den angivne type emittes fra source.

Nap-Message-Factory

Funktioner der gør det lettere at generere NAPMessages.

Eksempel på anvendelse af message factory
Code Block
languagejs
import { NAPEventCatalogue, NAPMessage } from 'nap-typescript-sdk';
import { v4 as UUID } from 'uuid';

const napMessageCurrentPatient = NAPEventCatalogue.v1.MessageFactory.createPatientOpenMessage(UUID())
const napMessageSessionClose = NAPEventCatalogue.v1.MessageFactory.createSessionCloseMessage(UUID());
const napMessageSessionError = NAPEventCatalogue.v1.MessageFactory.createSessionErrorMessage(UUID(), 'This is my error message', 'This is a longer description of the error message');
const napMessageRetrievedProjects = NAPEventCatalogue.v1.MessageFactory.createProjectsRetrievedMessage(UUID(), ['NAPTestWebShortName1', 'NAPTestWebShortName2', 'NAPTestWebShortName3', 'NAPTestWebShortName4', 'NAPTestWebShortName5', 'NAPTestWebShortName6']);
const napMessagewebAppSelected = NAPEventCatalogue.v1.MessageFactory.createWebAppSelectedMessage(UUID(), 'webAppUrl', 'webAppProducer', new Date(Date.now()), 'webAppShortName', 'webAppServiceEntry', ['1'])

FHIR-Value-getter

Funktioner, som gør det lettere at hente FHIR specifikke værdier ud af en NAPMessage. Disse kan bruges ved at importere namespacet FHIRValueGetter.

Eksempel på anvendelse

...

af FHIR-value-

...

setter

Følgende eksempel mapper en NAPMessage til en SAMLassertion og PatientInfo.

Code Block
languagejs
import { FHIRValueGetter, NAPMessage, NAPPatientInfo } from 'nap-typescript-sdk';
const sessionTokenpatientData: NAPPatientInfo = FHIRValueGetter.getSessionValue(napMessage);
const patientData: NAPPatientInfo = FHIRValueGetter.getSessionValue(napMessage);

filterEvent

Funktion, som gør det lettere at sortere i eventstrømmen og dermed subscribe til specifikke event typer

Eksempel på anvendelse af

...

filterEvent
Code Block
languagejs
import {filterEvents, NAPEventCatalogue} from 'nap-typescript-sdk';

nap.incoming$.pipe(
        filterEventsfilterEvent([
          NAPEventCatalogue.v1.SessionOpen,
          NAPEventCatalogue.v1.SessionClose,
        ])
      )

Fhir-Value-Setter

Enums som gør det nemmere at lave NAPMessages indholdende de værdier, som overholder FHIR standarden.

Komplet liste over hjælpeværdier.

Enum

FHIRResourceType.Patient

FHIRResourceType.Basic

FHIRSystem.NAP

FHIRIdentifierSystem.CPR

FHIRIdentifierSystem.NAPErrorMessage
.Basic

FHIRSystem.NAP

FHIRIdentifierSystem.CPR

FHIRIdentifierSystem.NAPErrorMessage
FHIRIdentifierSystem.NapErrorDescription

FHIRExtensionURL.WEBAPPSHORTNAMES

FHIRExtensionURL.WEBAPPSHORTNAME
FHIRExtensionURL.WEBAPPAUDIENCE
FHIRExtensionURL.WEBAPPSERVICEENTRY
FHIRExtensionURL.WEBAPPPRODUCER

FHIRExtensionURL.WEBAPPRELEASEDATE

FHIRExtensionURL.WEBAPPURL
FHIRExtensionURL.WEBAPPCATALOGUEVERSIONSFHIRIdentifierSystem.NapErrorDescription
Eksempel på anvendelse Fhir-Value-Setter (Session Error)

...

Generel kodedokumentation findes i biblioteket. Fuld implementation af eventkataloget ses i nap-reference-web her https://svn.nspop.dk/svnsrc/components/nap/nap-reference-web/trunk/.

...

 Session-

...

close

Følgende eksempel sender / modtager en Session-Open besked og får en SAMLassertion tilbage:Close besked når ønsker, at blive logget ud.

Code Block
languagejs
import { NapAngularService } from 'nap-angular-sdk';
import { filterEventsfilterEvent, NAPEventCatalogue, NAPMessage } from 'nap-typescript-sdk';
import { v4 as UUID } from 'uuid';

export class MyComponent {
	
	// proxy for SAMLAssertion
	public session$: Observable<NAPMessage | undefined> = 
		this.napSDK.incoming$.pipe(
		filterEvents([NAPEventCatalogue.v1.SessionOpen, NAPEventCatalogue.v1.SessionClose])
	);
		//inject the nap-angular-sdk service
	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);

export class MyComponent {
	
	innerLogout = new Subject<undefined>();
  
	logOut$: Observable<undefined> = merge(
    this.innerLogout,
    this.napSDK.incoming$.pipe(
      filterEvent(NAPEventCatalogue.v1.SessionClose),
      map(() => undefined)),
  	);
	
	//inject the nap-angular-sdk service
	constructor(private napSK: NapAngularService) {
	}

	/**
   * TriggerHandle logout eventevents
   */
  logout(): void {
    const napMsg: NAPMessage = {
      date: new Date().toISOString(),
      id: UUID(),
      event: { type: NAPEventCatalogue.v1.SessionClose },
    };
    this.napSDK.sendMessage(napMsg);
	this.innerLogout.next(undefined);
  }
}

Patient-Open og Patient-close

...

Nap-react-sdk udstiller en komponent kaldet NAPContextProvider. Denne komponent sørger for at kalde createNAP() fra nap-typescript-sdket og dermed initialisere kontekstbroen i React.UseEffect(), som kaldes efter render() kaldes første gang.

Samtiditig subscribes der på de forskellige messagestreams, og deres emits håndteres i React.state på Contextprovideren.

De forskellige subscriptions og håndtag håndteres i react.useCallback. De forskellige states og methodemetode-håndtag pakkes alt sammen i en Context.

...

Denne kontekst kan blive injectet i child elementer ved kalde `createNAP()`. Hvis denne funktion kaldes udenfor en NapContext kaster det kastes en fejl.

Effekten for anvenderen bliver, at broen initialiseres som en singleton, og at beskeder sendt over broen opdatere context state af applikationen, og på den baggrund vil React kalder Render().

Eksempel på anvendelse af nap-react-sdk

...

SessionClose og latestError

Følgende eksempel viser hvordan man kan anvende nap-react-sdk til at vise og sende beskeder:

Code Block
languagejs
import { NapContextProvider, NAPEventType, useNap } from 'nap-react-sdk';
import React from 'react';
import { v4 as UUID } from 'uuid';

const IncomingMessageComponent: React.FC = () => {
  const napContext = useNap()

  return <div> {JSON.stringify(napContext.latestIncoming)}</div>
}

const IncomingErrorsComponent: 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: UUID(),
          event: { type: NAPEventType.SessionOpenSessionClose }
        })
      }}
    >
      Send message
    </button>
  )
}

const App = () => {

  return (
    <>
      <NapContextProvider>
        <IncomingMessageComponent></IncomingMessageComponent>
		<IncomingErrorsComponent></IncomingErrorsComponent>
        <PostMessageComponent></PostMessageComponent>
      </NapContextProvider>
    </>
  )
}

export default App

...