Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Low level Rafiki Intro blog post #79

Merged
merged 5 commits into from
Sep 23, 2024
Merged

Low level Rafiki Intro blog post #79

merged 5 commits into from
Sep 23, 2024

Conversation

njlie
Copy link
Contributor

@njlie njlie commented Aug 23, 2024

This is a Tech Blog post that goes over the Rafiki codebase in as efficient a manner as possible to set the reader up for success for contributing to the codebase.

Comment on lines 42 to 43
* [KoaJS](https://koajs.com/)
* [AdonisJS](https://docs.adonisjs.com/guides/preface/introduction)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should mention knex as well here


Familiarity with these frameworks will be valuable in understanding how Rafiki works, and with understanding the rest of this post.

### The Rafiki Backend
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we mention the ILP connector as well?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have to.

* An [`auth`](https://github.com/interledger/rafiki/tree/main/packages/auth) package that provide third parties with a method of acquiring authorization to manage Open Payments resources on the Rafiki instance's associated `backend` package.
* A [`frontend`](https://github.com/interledger/rafiki/tree/main/packages/frontend) that serves as an Admin-level UI for that Rafiki instance. It allows the manager of that Rafiki instance to directly manage items such as other peers on the Interledger network or what currencies it supports.

### The `backend` and `auth` stacks
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be good to include the other packages in there? Maybe we can add a table of contents in here and just one sentence explain what they are? (and how they are managed with pnpm?)

author: Nathan Lie
author_url: https://www.linkedin.com/in/nathan-lie-138a73121
tags:
- Interledger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Interledger

We removed Blair's Interledger tag too, since we are talking about Interledger engineering blog it seems redundant.

---
layout: ../../layouts/BlogLayout.astro
title: "Architecture Breakdown of Rafiki (Pending Title)"
description:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need something filled in here please.


AdonisJS is used to perform [dependency injection](https://docs.adonisjs.com/guides/concepts/dependency-injection) on the services used by each package to perform business logic.

Additionally, both packages extend a [GraphQL API](https://github.com/interledger/rafiki/pull/2828#discussion_r1704862655) that serves as an Admin API.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link doesn't seem to be correct.


### The Rafiki Backend

As mentioned before, the Rafiki Backend manages Open Payments resources. These resources are managed by services attached to an inversion-of-control (IoC) container via dependency injection with AdonisJS, as also mentioned previously. To see this in action, the [`/src/index.ts`](https://github.com/interledger/rafiki/blob/main/packages/backend/src/index.ts) is the best place to look. Take [this example](https://github.com/interledger/rafiki/blob/main/packages/backend/src/index.ts) of how the service for handling incoming payment routes gets injected into the IoC container:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two links here are identical.


As mentioned before, the Rafiki Backend manages Open Payments resources. These resources are managed by services attached to an inversion-of-control (IoC) container via dependency injection with AdonisJS, as also mentioned previously. To see this in action, the [`/src/index.ts`](https://github.com/interledger/rafiki/blob/main/packages/backend/src/index.ts) is the best place to look. Take [this example](https://github.com/interledger/rafiki/blob/main/packages/backend/src/index.ts) of how the service for handling incoming payment routes gets injected into the IoC container:

```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```
```ts wrap


These services are then attached to routes in the [`/src/app.ts`](https://github.com/interledger/rafiki/blob/main/packages/backend/src/app.ts) file. The `app.ts` file is a great place to work backwards from and see which routes exist on the backend server and what services are used to complete the operations presented by the routes. Take [this route](https://github.com/interledger/rafiki/blob/main/packages/backend/src/app.ts#L432-L454) for example:

```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```
```ts wrap


### The Rafiki Backend

As mentioned before, the Rafiki Backend manages Open Payments resources. These resources are managed by services attached to an inversion-of-control (IoC) container via dependency injection with AdonisJS, as also mentioned previously. To see this in action, the [`/src/index.ts`](https://github.com/interledger/rafiki/blob/main/packages/backend/src/index.ts) is the best place to look. Take [this example](https://github.com/interledger/rafiki/blob/main/packages/backend/src/index.ts) of how the service for handling incoming payment routes gets injected into the IoC container:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
As mentioned before, the Rafiki Backend manages Open Payments resources. These resources are managed by services attached to an inversion-of-control (IoC) container via dependency injection with AdonisJS, as also mentioned previously. To see this in action, the [`/src/index.ts`](https://github.com/interledger/rafiki/blob/main/packages/backend/src/index.ts) is the best place to look. Take [this example](https://github.com/interledger/rafiki/blob/main/packages/backend/src/index.ts) of how the service for handling incoming payment routes gets injected into the IoC container:
As mentioned before, the Rafiki `backend` manages Open Payments resources. These resources are managed by services attached to an inversion-of-control (IoC) container via dependency injection with AdonisJS, as also mentioned previously. To see this in action, the [`/src/index.ts`](https://github.com/interledger/rafiki/blob/main/packages/backend/src/index.ts) is the best place to look. Take [this example](https://github.com/interledger/rafiki/blob/main/packages/backend/src/index.ts) of how the service for handling incoming payment routes gets injected into the IoC container:


Like the `backend`, the `auth` server also extends a GraphQL API to perform admin functions. The API is modeled by this [GraphQL schema](https://github.com/interledger/rafiki/blob/main/packages/auth/src/graphql/schema.graphql).

### The Rafiki Frontend
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### The Rafiki Frontend
### Rafiki Admin

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would "The Rafiki Admin Frontend" work too? Since the package itself is called frontend in the repo I thought it might be a good way to help connect those two dots.


### The Rafiki Frontend

The Rafiki has a React-based (specifically [Remix](https://remix.run/docs/en/main)) frontend with server-side rendering that consumes the GraphQL API extended by the `backend` server.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The Rafiki has a React-based (specifically [Remix](https://remix.run/docs/en/main)) frontend with server-side rendering that consumes the GraphQL API extended by the `backend` server.
Rafiki has a React-based (specifically [Remix](https://remix.run/docs/en/main)) frontend with server-side rendering that consumes the GraphQL API extended by the `backend` server.

The Rafiki has a React-based (specifically [Remix](https://remix.run/docs/en/main)) frontend with server-side rendering that consumes the GraphQL API extended by the `backend` server.
In general, the [name of a file](https://github.com/interledger/rafiki/tree/main/packages/frontend/app/routes) dictates how the app constructs its routes. For example, the file [assets.create.tsx](https://github.com/interledger/rafiki/blob/main/packages/frontend/app/routes/assets.create.tsx) is expressed as `/assets/create` in the frontend app. Path parameters are denoted by a `$` sign, so the file [assets.$assetId.tsx](https://github.com/interledger/rafiki/blob/main/packages/frontend/app/routes/assets.%24assetId.tsx) might be expressed as `/assets/1234-1234-12345678`, where the `$assetId` portion of the file name stands in for an identifier in the final route.

<LargeImg src="/developers/img/blog/2024-08-05/rafiki-admin-screen.png" alt="A screenshot of the Rafiki Admin UI" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<LargeImg src="/developers/img/blog/2024-08-05/rafiki-admin-screen.png" alt="A screenshot of the Rafiki Admin UI" />
![A screenshot of the Rafiki Admin UI](/developers/img/blog/2024-08-05/rafiki-admin-screen.png)

This doesn't require the ability to view it in a separate screen for small details to be more visible.

To help provide an idea of what integrating with Rafiki would be like, the local Docker environment also starts up a couple of [Mock Accout Servicing Entities (Mock ASEs)](https://github.com/interledger/rafiki/tree/main/localenv/mock-account-servicing-entity) to represent integrators of Rafiki.
These Mock ASEs have [pages that display information for individual accounts](https://github.com/interledger/rafiki/blob/main/localenv/mock-account-servicing-entity/app/routes/accounts.%24accountId.tsx) on their respective Rafiki instances. Crucially, they each also host [pages that collect authorization from account owners](https://github.com/interledger/rafiki/blob/main/localenv/mock-account-servicing-entity/app/routes/consent-screen.tsx) for payments made using grants from the `auth` server.

<LargeImg src="/developers/img/blog/2024-08-05/mock-ase-consent-screen.png" alt="A screenshot of the Mock ASE's consent screen" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<LargeImg src="/developers/img/blog/2024-08-05/mock-ase-consent-screen.png" alt="A screenshot of the Mock ASE's consent screen" />
![A screenshot of the Mock ASE's consent screen](/developers/img/blog/2024-08-05/mock-ase-consent-screen.png)

@JoblersTune
Copy link
Contributor

I love this post, great writing style! And so valuable to make this info available, also for new team members!

Copy link
Member

@sabineschaller sabineschaller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please merge in main and apply Sarah's comments to the header. Otherwise it doesn't build.


* [Open Payments](https://openpayments.dev/introduction/overview/)
* [Interledger](https://interledger.org/developers/get-started/#how-does-interledger-work)
* [Rafiki](https://rafiki.dev/introduction/overview/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it weird that this is a post on Rafiki and it assumes pre-knowledge on Rafiki? I know you are saying that it assumes high level pre-knowledge, but can we maybe phrase it a bit differently here?


Rafiki is comprised primarily of three packages:

* A [`backend`](https://github.com/interledger/rafiki/tree/main/packages/backend) package that extends an API for managing Open Payments resources like Incoming or Outgoing Payments.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backend has multiple APIs, including the one to send ILP packets to. Should we mention that here?

* [Interledger](https://interledger.org/developers/get-started/#how-does-interledger-work)
* [Rafiki](https://rafiki.dev/introduction/overview/)

## Components
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add an (updated?) architecture diagram here?


Familiarity with these frameworks will be valuable in understanding how Rafiki works, and with understanding the rest of this post.

### The Rafiki Backend
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have to.

pnpm localenv:compose up
```

With this environment live, the Admin GraphQL Endpoints can be demoed using [Bruno](https://www.usebruno.com/). [The Rafiki repository contains a collection](https://github.com/interledger/rafiki/tree/main/bruno/collections/Rafiki) which contains example calls for all of the GraphQL endpoints on both the `backend` and `auth` servers. It also contains example flows for certain actions in Open Payments.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also contains all the Open Payments endpoints (plus the example flows).


<LargeImg src="/developers/img/blog/2024-08-05/bruno-screen.png" alt="A screenshot of the Bruno UI" />

To help provide an idea of what integrating with Rafiki would be like, the local Docker environment also starts up a couple of [Mock Accout Servicing Entities (Mock ASEs)](https://github.com/interledger/rafiki/tree/main/localenv/mock-account-servicing-entity) to represent integrators of Rafiki.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say it's "just" 2, not a couple 😉

---
layout: ../../layouts/BlogLayout.astro
title: "Architecture Breakdown of Rafiki (Pending Title)"
description: ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please put something here. Otherwise it will not look great on the overview page.

@@ -0,0 +1,218 @@
---
layout: ../../layouts/BlogLayout.astro
title: "Architecture Breakdown of Rafiki (Pending Title)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any thoughts here or is this what it is?

* [Open Payments](https://openpayments.dev/introduction/overview/)
* [Interledger](https://interledger.org/developers/get-started/#how-does-interledger-work)

This article also assumes that the reader already have high-level knowledge of [Rafiki](https://rafiki.dev/introduction/overview/) itself, and that they understand on that level how it accomplishes being an Interledger node and an Open Payments server.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This article also assumes that the reader already have high-level knowledge of [Rafiki](https://rafiki.dev/introduction/overview/) itself, and that they understand on that level how it accomplishes being an Interledger node and an Open Payments server.
This article also assumes that the readers already have high-level knowledge of [Rafiki](https://rafiki.dev/introduction/overview/) itself, and that they understand on that level how it accomplishes being an Interledger node and an Open Payments server.


Rafiki is comprised primarily of three packages:

* A [`backend`](https://github.com/interledger/rafiki/tree/main/packages/backend) package that extends an API for managing Open Payments resources like Incoming or Outgoing Payments, an Admin API, and an API from the Interledger connector to .
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is something missing at the end of this sentence.

Rafiki is comprised primarily of three packages:

* A [`backend`](https://github.com/interledger/rafiki/tree/main/packages/backend) package that extends an API for managing Open Payments resources like Incoming or Outgoing Payments, an Admin API, and an API from the Interledger connector to .
* An [`auth`](https://github.com/interledger/rafiki/tree/main/packages/auth) package that provide third parties with a method of acquiring authorization to manage Open Payments resources on the Rafiki instance's associated `backend` package.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auth has an Admin API, too. 🙃


### The `backend` and `auth` stacks

Both the `backend` and `auth` packages are largely built in the same way. They both leverage the same two Node.js frameworks:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You list three below 😉

Comment on lines 60 to 64
KnexJS is an ORM that manages calls made to Rafiki's Postgres database.

Additionally, both packages extend a [GraphQL API](https://github.com/interledger/rafiki/blob/main/packages/backend/src/graphql/schema.graphql) that serves as an Admin API.

Finally, [ObjectionJS](https://vincit.github.io/objection.js/) is used as an ORM to perform database operations.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should talk about Knex and Objection together. It sounds like the do the same.


Finally, the `backend` also launches a GraphQL server that extends an API defined by [this schema](https://github.com/interledger/rafiki/blob/main/packages/backend/src/graphql/schema.graphql).

In order fulfill the payments described in Open Payments resources and maintain peering relationships, Rafiki runs an instance of an Interledger Connector, acting as its node on the Interledger network.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you maybe want to go into the connector in your next blog post and announce that here? Otherwise I think this is a bit too little on the connector.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that abstracting Interledger within this blog post feels in line with Rafiki's purpose for existing in the first place. The connector I could see warranting its own blog post.


## Seeing Rafiki In Action

If Docker is installed, the whole environment can be started with a single command:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If Docker is installed, the whole environment can be started with a single command:
If Docker is installed, the whole environment can be started locally with a single command:

@JoblersTune
Copy link
Contributor

JoblersTune commented Sep 20, 2024

The front matter fields still need some attention

title: "Architecture Breakdown of Rafiki (Pending Title)"
description: ''

Other than that, it LGTM

Copy link
Member

@sabineschaller sabineschaller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Let's get it out there!

@njlie njlie merged commit 4e690c2 into main Sep 23, 2024
1 check passed
@njlie njlie deleted the nl/rafiki-low-level-intro branch September 23, 2024 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

5 participants