Koios-faucet is a back-end service for the Koios platform. It is primarily used as a middleware for handling certain functions that should be done off-chain.
The architecture currently follows a Service-Based Software Architecture. Modules can talk down but not up. For example, a service should not be able to call a controller and a controller should not be able to call a router. But within a Service-Based Architecture we do allow services to call each other, only if needed. This is because each service has its own domain. Think of Service-Based as Domain Driven Design.
- Routes, the different API endpoints the client is able to call. The requests get routed to their corresponding controler.
- Controllers, this is where the API requests get handled through the different endpoints.
- Services, controllers call their corresponding service, in the service business logic gets handled.
- Repositores, when a service needs to make a call to a database it will be handled within its corresponding repository component (not created yet not needed)
- Interfaces, folder for all the interfaces that are being used.
- Json, folder for static .json data.
For adding a new endpoint a few things need to be created, let's call the new endpoint: NFT. We want to get NFTs from a certain address.
In the routes folder create a new: NFTRouter.ts
import express from "express";
//Don't worry about the controller yet
import * as NFTController from "../controllers/NFTController";
export const NFTRouter = express.Router();
NFTRouter.route("/:address").get(NFTController.get);
In the controller folder create a new: NFTController.ts
import { NextFunction, Request, Response } from "express";
//Don't worry about the service in this step yet
import { fetchNFTs } from "../services/NFTService";
export const get = async (req: Request, res: Response, next: NextFunction) => {
const NFTs = await fetchNFTs(req.params.address);
if (NFTs) {
return res.send(NFTs);
}
};
In the services folder create a new: NFTService.ts
export const fetchNFTs = async (address: string) => {
const fetchedNFTs = //fetch NFTs implementation;
return NFTs
};
Using this pattern may cost some more time in the beginning, but it makes everything much more expandable and manageable.