rads-server
v2.62.1
Published
GraphQL API layer for CosmosDB and other Azure services.
Downloads
4
Readme
RADS
Rapid Application Development System
RADS is a GraphQL API layer for Azure that makes working with it more pleasant experience for developers of any kind. Especially helpful in "jumpstarting" software projects.
Packages in this repository:
rads-server - node.js library that creates well-documented GraphQL API for functionality needed by typical app. Compatible with Azure functions. Features:
- Database access layer (CosmosDb. Includes Db maintenance background tasks, automatic denormalization and schema manager)
- Authentication - Azure AD B2C (incl. role-based authorization)
- File storage (Azure blob storage)
- Push notifications (Azure Notifications Hub)
- Crash analytics
rads - JS (Browser & node.js) library for consuming rads APIs and access database. Includes advanced ability to work offline.
rads-ui - Web application to access all functionality provided by rads-server.
Database access layer
This is core feature of RADS. It presents innovative (eh, maybe too innovative to be honest) approach to database layer.
For most apps, either SQL or Document type databases are used nowadays. SQL is built to store normalized data - meaning that designing it's schema is very straightforward, and it supports most queries you can imagine with decent performance. NoSql (Document) databases are built to store data in denormalized fashion, which means that it can be very fast, but only for certain queries, and designing schema is hard.
::: NoSQL vs SQL
NoSQL is faster, SQL is easier.
:::
In RADS, we use Document database (CosmosDB) to store data, but make some adjustments to make denormalizing easier. See comparison below ("D" stands for "denormalized").
| Feature | raw MsSql | raw CosmosDb | rads-server | | ----------------------------- | ----------------- | ------------------------- | --------------------------- | | Data | Normalized | Denormalized | Denormalized | | API | - SQL | +- REST | + GraphQL | | Schema design complexity | + Straightforward | - Designed around queries | Designed around entities | | Horizontal scale | - Impossible | + Automatic | + Automatic | | Indexing | - Manual | + Automatic | + Automatic | | Data format | - Table | + JSON | + JSON | | Transactions | + Excellent | - Not supported | - Not supported | | --------------------------- | ----------------- | ------------------------- | --------------------------- | | JOIN - performance | - Slow | - Slow | - Slow | | JOIN - implementation | + Simple | - Hard (manual) | + Simple | | JOIN WHERE - performance | - Slow | - Slow | - Slow | | JOIN WHERE - implementation | + Simple | - Hard (manual) | - Hard (manual) | | Aggregates - performance | + Fast | - Slow | - Slow | | Aggregates - implementation | + Simple | - Hard (manual) | - Hard (manual) | | --------------------------- | ----------------- | ------------------------- | --------------------------- | | D JOIN - performance | - Slow | + Fast | + Fast | | D JOIN - implementation | - Hard | - Hard (manual) | + Simple | | D JOIN WHERE - performance | - Slow | + Fast | + Fast | | D JOIN WHERE - implementation | - Hard | - Hard (manual) | + Simple | | D Aggregates - performance | - Slow | + Average | + Average | | D Aggregates - implementation | - Hard | - Hard (manual) | + Medium |
In other words - properly denormalized CosmosDB is can't be beaten in performance department, but it introduces problems:
- wiring it up requires significant amount of application-level manual denormalization that keeps denormalized data up-to-date
- it's hard to do queries that DB was not optimized for - again, application-level code is needed.
- Evolving schema (e.g. adding denormalized fields) often will lead to change in data structure, which will lead to need to change code on the clients.
- Consequence of 3 - server devs need to understand client needs very well to design proper schema right at the start.
RADS provides API layer on top of CosmosDb database that aims to solve those problems.
:::tip RADS db - vision
- Give developers additional functionality on top of CosmosDb without sacrificing performance.
- Allow optimizing schema performance via denormalization without requiring clients to change their queries.
:::
RADS features - database
GraphQL API from schema definition
70%.
You define your database schema in SDL. Just from that schema, entire GraphQL API layer is generated automatically.
As opposed to raw CosmosDb, it is strictly-typed, and follows strict naming standards. It also provides developers with autocomplete for easier query construction.
- queries - done
- upserts/deletes - done
- bulk upserts/deletes - done
- where - done
- aggregates - WIP
- groupBy - WIP
Common schema operations
Completed.
@stringCase
- allows to force uppercase / lowercasecreatedAt/updatedAt
- automatic timestampscreatedBy/updatedBy
- automatic user access logs@default
- set default value if it was not provided by the user
JOINs
Completed.
CosmosDB supports "in-document" JOINs, but in 99% cases you want to do cross-document JOINs. In raw CosmosDb you need to
write custom application code for it. RADS does it for you with @relation
attribute.
Bulk upsert / delete
Completed.
In CosmosDb you need to write custom transactions for it. RADS has them built-in (deleteTcUsers(where: ...)
and
upsertTcUsers(data: [...])
).
Denormalization - related entities fields
Very simple kind of denormalization - provided by RADS with @relation(denorm: "name, type", async: false)
. Is kept
up-to-date automatically. async: true
will update denormalized fields on background (instead of waiting for it during
insert operation).
Denormalization - computed / precomputed fields
40%.
This is a form of denormalization, provided via @computed
and @precomputed
directives.
@computed
= calculate during query. Don't store in database.@precomputed
= store in database, calculate and update during relevant entity upsert.
In it's basic variant, it requires developer to fill fields marked with those directives in application code manually.
However, some commonly used logic for precomputed fields is available out-of-the-box:
incrementalNumber: Int! @precomputed(autoincrement: "myCounter")
- WIPPosts: [TcPost!]! @relation @precomputed(query: "tcPosts", where: { createdBy: "." }, path: "nodes")
- WIP
Partition key change
45%
Allows changing partition key strategy (@partitionKey
) for entity without making changes to client code.
Entity Logs
0%
Allows storing full history of entity changes (@logs
)
Event sourcing
85%
Entity logs on steroids. Allows treading entity as merge of series of events. Enabled via @eventSourcingAggregate
and
@eventSourcingEvent
.
Migrations
0%
Allows to migrate data on-the-fly without going offline. Gives options for common migrations (e.g. new field with default value) without going offline.
RADS Explorer
65%
Provides friendly UI for managing database. Includes advanced filtering and bulk changes.
RADS BI
20%
Provides friendly UI for building reports, dashboards and spreadsheets from data stored in RADS