FrEDA

FrEDA

  • Docs
  • Tutorial
  • Demo

›Backend

Präambel

  • Architektur
  • MonoRepo Struktur

External

  • PostgreSQL / Postgraphile
  • GraphiQL

Backend

  • GraphQL Server
  • GraphQL-Modules
  • TypeGraphQL
  • GraphQL-Playground
  • Besonderheiten
  • REST-Endpoints

Frontend

  • FrEDA ReactJS-Basics
  • Common Frontend-Library
  • CLI-Tools

Deploy

  • Deployment

Roadmap

  • geplante Weiterentwicklung

Besonderheiten

TypeORM

Für die Erstellung der PostgresSQl-Tabellen für die FrEDA-App wie Nutzer, Rollen, Geräte o.ä. wird das Framework TypeORM genutzt. Dieses ermöglicht über Code-First und TypeScript Tabellen-Schemas zu spezifizieren. Beim Einrichten des Freda-Frameworks wird über yarn setup das Einrichten der Tabellen vorgenommen. Über TypeORM lassen sich auch Daten abfragen/ändern/löschen. Aufgrund der Verwendung von GraphQL-Bindings wurde diese Art von Datenmanipulation jedoch in den meisten Fällen umgangen, um die Nutzung des Freda-Framworks an den meisten stellen einheitlich zu halten, als wäre die interne Datenverwaltung ein externer Datenservice.

Für eine ausführliche Doku von TypeORM bitte folgende Seite besuchen: https://typeorm.io

GraphQL-Binding

Über GraphQL-Binding können interne Abfragen in Resolvern oder Providern auf Datenbanken durchgeführt werden. Hierzu gibt es ein extra GraphQL-Module, welches per Dependency-Injection in die jeweiligen unter GraphQL-Modules durchgereicht wird. Siehe:

backend/freda-middleware/src/modules/fredaGraphQLProxy/index.module.ts

export const getFredaGraphQLProxyModule = (fredaGraphQlSchema: GraphQLSchema) => {

  const mergedSchema = mergeSchemas({
    schemas: [
      fredaGraphQlSchema,
    ],
  });

  const fredaGraphQlSchemaBinding = new Binding({schema: mergedSchema});

  return new GraphQLModule({
    name: 'fredaGraphQLProxy',
    providers: () => [{
      provide: 'fredaGraphQlSchemaBinding',
      useValue: fredaGraphQlSchemaBinding,
    }],
    extraSchemas: () => [
      mergedSchema,
    ],
    resolversComposition: {
      'Mutation.deleteUserById': [preventDeleteMiddleware(1, 'Nutzer mit der ID 1 kann nicht gelöscht werden!')],
      'Mutation.deleteRoleById': [preventDeleteMiddleware(1, 'Rolle mit der ID 1 kann nicht gelöscht werden!')],
    },
  });
};

Das Modul erlaubt es, auf Freda-Nutzerdaten über folgende interne Queries mit folgender Syntax zuzugreifen:

const fragment = `fragment EnsureFullName on User { nodeId id password firstName lastName email userRolesRolesByUserId { nodes { roleByRoleId { nodeId id name } } } }`;
const graphileUser = await this._binding.query.userByEmail({email}, addFragmentToInfo(info, fragment));

Das Beispiel fragt einen Nutzer per Mail ab. Das nötige Modul dafür ist graphql-binding, welches vorab importiert werden muss.

Ähnliche Ansätze gibt es hier:

  • VulcanoJs: GraphQl-Server Framework: https://docs.vulcanjs.org/server-queries.html
  • PrismaJS: ORM-Like Framwork für GraphQL und mehr: https://www.prisma.io/

GraphQL-Transforming

Für das Änderung von GraphQl-Schemas wird das Tool "graphql-tools" genutzt.

Details hierzu findet man hier: https://www.graphql-tools.com/

PubSub

PubSub ist ein Mechanismus, der es erlaubt Events über ein EventSystem an die Infrastruktur zu übermitteln. Damit lassen sich bspw. Logging-Events triggern, welche auch per Echtzeit und GraphQL-Subscription an den Clint weiterreichen lassen. Auch Chat-Funktionen o.ä. lassen sich damit umsetzen. Als Basis-Evetsystem gibt es mehrere Möglichkeiten, sogennante Communication-Bridges, siehe:

https://graphql-modules.com/docs/recipes/communication-between-modules#existing-implementations-for-pubsub

Freda verwendet aktuell die Implentierung einer Communication-Bridges von Postgres. Hier ist diese Implementiert als GraphQL-Module backend/freda-middleware/src/modules/common/index.module.ts

import { GraphQLModule } from '@graphql-modules/core';
import { ProviderScope } from '@graphql-modules/di';
import { PubSub } from 'graphql-subscriptions';

const { PostgresPubSub } = require('graphql-postgres-subscriptions');

const pubsub = new PostgresPubSub({
 host: process.env.FREDA_DB_HOST,
 port: process.env.FREDA_DB_PORT,
 user: process.env.FREDA_DB_USERNAME,
 password: process.env.FREDA_DB_PASSWORD,
 database: process.env.FREDA_DB_NAME,
 schema:process.env.FREDA_DB_SCHEMA
});

export const commonModule = new GraphQLModule({
 name: 'common',
 providers: () => [
   {
     provide: PubSub,
     scope: ProviderScope.Application,
     useValue: pubsub,
   },
 ],
}); 

JWT-Token

Ein JWT Token wird für die Authentifizierung genutzt. Er beinhaltet alle wesentlichen Daten und kann nur mithilfe eines Schlüssel serverseitig verifiziert werden.

Genaue Infos dazu findet man hier: https://jwt.io/

Cookie-Auth

Aktuell verwendet der GraphQL-Gateway-Server Cookie-Authentifizierung. D.h. der JWT Token wird bei jedem Request im Header als Cookie-Set mitgeliefert. Ein Auth-Cookie ist dabei immer an seine HauptDomain gekoppelt, weshalb die Authentifizierung über mehrere Anwendungen, welche die gleiche Basis-Domain beinhalten, geteilt werden kann.

Das ist auch der Grund warum sowohl die freda-app als auch die freda-adminui mit einem einzigen Login bedienbar ist.

Überlegung ist hier auf eine Header-Auth zu wechseln, da so auch andere Anwednungen außerhalb eines Browser in der Lage sind, sich gegen den GraphQL-Gateway zu authentifizieren, was mit der aktuellen Lösung und Umsetzung nicht möglich wäre.

← GraphQL-PlaygroundREST-Endpoints →
  • TypeORM
  • GraphQL-Binding
  • GraphQL-Transforming
  • PubSub
  • JWT-Token
  • Cookie-Auth
FrEDA
Docs
Getting StartedFrontendBackendFrEDA Users
Tutorial
RequirementsSetup DevelopmentQuick run
Mehr
Prodat-SQLHochschule MittweidaDEVTIM IT Softwareentwicklung
Facebook Open Source
Copyright © 2021 Prodat-SQL. Built with ❤ and Docusaurus.