-
Notifications
You must be signed in to change notification settings - Fork 0
Technical documentation
The amos-ss2021-project2-context-map uses three runtime components: Client, Backend and Database.
The Client is a single-page web app (SPA) presented by an internet browser. The client communicates with the Backend via HTTP-Requests to submit queries that are generated by the Client’s user. The Backend translates those domain-specific queries into CYPHER queries, that are forwarded to an external neo4j-graph Database. This is done so that the Database does not need to be visible and accessible directly to the end-user and to provide an extra layer of abstraction to the specific database type. The query result received as a response from the Database is projected in a domain-specific model and then redirected to the Client.
The frontend is a React SPA written in TypeScript.
- (UI-)Components
- Components are responsible for displaying information to the user. These components are "what the user sees". Components retrieve their dynamic data either from Services or Stores, but never from anywhere else (e.g. no direct
fetch
-calls).
- Components are responsible for displaying information to the user. These components are "what the user sees". Components retrieve their dynamic data either from Services or Stores, but never from anywhere else (e.g. no direct
- Services
- Services are responsible for retrieving data. In our case, the only data source is our own backend.
- Services that make HTTP requests use the
HttpService
to unify app-wide settings and behaviour, e.g. common error mapping (error code to custom error object).
- Stores
- Stores are singleton instances that contain the app's state as single point of truth and work according to the observer pattern.
- More information in Store Documentation.
The SPA provides multiple features and components. These use services that are using a HTTPService
that is making HTTP-requests to the backend. The individual features and components are summarized here.
-
Graph view
The data is represented by a conventional mathematical graph. -
Filter
The specific nodes and relationships can be filtered by the user, so only the parts of the graph that are wanted are displayed. For that, theSchemaService
requestsEntityType
's that represent the entity-categories the user can filter. In these categories, the specific properties the user can select are fetched from theFilterService
. It returns anEntityTypeFilterModel
that essentially gives the properties and its values for a given entity-type. After that, theFilterService
sends a HTTP-request with aFilterQuery
to the backend. The backend then returns aQueryResult
that is converted to a visible graph-object. -
Search bar
The Searchbar is a component that queries the backend for a specific search query input. Requests are sent to the backend only if the typing is finished (recognized by a short break after typing). It uses theError Component
in the case of errors. If search results are found, they are displayed in a floating container.
The Backend is created with NestJS and written in TypeScript. It provides background processing for each feature or component. The HTTP-requests from the client are recieved by controllers and forwarded to services. These services make requests to the database with a nestjs-compliant Neo4jService
. The requests that are made and the background logic of the features and components are summarized here.
The backend is structured in the following component types:
-
Controller (named like
<description>.controller.ts
)
A controller is responsible for answering HTTP requests by providing endpoints and parsing incoming HTTP requests (like parameters). Controllers should not contain contain domain logic and only parse incoming requests, forward them to services, and then responding with the results from the service. -
Service (named like
<description>.service.ts
)
A service is responsible for the domain logic. They work completely independent from the possible endpoints (like HTTP endpoints).
-
Filter
TheFilterService
provides methods for filtering certain entities from the database based on a givenFilterQuery
, and also for queryingEntityTypeFilterModel
's that are used for displaying the different entities to the filter-view. For the execution ofFilterCondition
s a filter-condidition executor is used. There are dedicated executors edges (EdgeFilterConditionExecutor
) and nodes (NodeFilterConditionExecutor
). For puttingFilterCondition
's together, aFilterConditionBuilder
is used. -
Schema
TheSchemaService
provides methods for queryingEntityType
's that are displayed in the filter-view. -
Search
The search is performed via a in memory search with minisearch. This is done since this provides more flexibility like searching for attributes. Furthermore, we cannot assume that the required DB has a full search index nor that the program has write access, so we decided against an in database search.
The database uses a preprocessed neo4j northwind dump. This dump is loaded into a docker container that can be accessed by an URL that is set in the run configurations or in start-database.js.
The Frontend is made up out of single components that each represent and present different and dedicated aspects of the user interface.
To coordinate the components, they interact with a Store/State-Manager, which is the single source of truth for data in the app. The store communicates with Services that perform requests to the Backend server.
The Client runs via HTML, CSS and TypeScript in a Browser. React is used as the technology to render the pages.
The Backend is a NodeJS Server using NestJS and it runs in a docker container.
The Database is a neo4j database.