fullyAPI: A RESTful Framework

fullyAPI blog graphic

We have recently released our RESTful API framework: fullyAPI. It is written atop expressJS and generates a admin portal that self-documents endpoints and data models as you register them with the application during buildout. For non-technical people, this would be like if you built a house and it automatically generated blueprints of itself based on what you built. We are pretty excited about it. The rest of this blog post is really geared toward developers and assumes you have a pretty solid understanding of backend components and API development.

The self-documentation admin portal allows admin, super, and documentation security role users to log into a central hub that includes endpoint & data model documentation, as well as the project README, and any available download of postman collection files the developer has zipped to make public.

fullyAPI handles core functions such as server boot, session invalidation & management, security role enforcement, db connection management, request routing, and a few general services available throughout the framework with functions such as updateRow() or insertRow() for modifying or creating a database entries for a registered data model.

Internal Schema

fullyAPI autogenerates 4 name-spaced tables for users and associated session management, and has a small collection of core endpoints that allow you to boot a project with functioning authentication endpoints from the start. The tables are relational and can have their columns expanded to accommodate any customizations you may wish to make. We do not recommend altering any existing table columns, as this may break internal functionality.

Stack

FullyAPI is written in typescript compiled to node, and has an Angular 12 frontend as the documentation portal. It is available on npm as npm i fully-api and provides all this functionality at an unpacked size of only 1.5MB. We use linting during bundling, and Mocha and Chai for unit testing our core endpoints. We suggest you unit test your API endpoints with the tool of your choice.

Intention/Who is fullyAPI for?

fullyAPI is intended to be a starting point for mid to senior level developers building custom APIs. It is designed to run on a Postgres 10+ database and comes pre-installed with the Postgres extension uuid-ossp, which is used for primary key generation on system tables. We suggest keeping this pattern and using the following definition for primary keys throughout your application data tables: id VARCHAR(36) NOT NULL DEFAULT uuid_generate_v1() PRIMARY KEY. We also suggest including updated_at and created_at timestamp fields in all of your data models. If you use the updateRow() function on a table with an updated_at field registered in the data model file, it will update the timestamp for you when constructing each UPDATE query. Aside from select by id, we do not have an ORM style mechanism to select entities out of the database, as you are a developer and can create all your own custom queries and query functions in your dataAccess service extension file.

Self-Documenting Portal: README.md

DB Management

As the developer, you will need to create the database you wish to use as the system database, and provide the connection information in the config file before booting the system. You will be responsible for managing your own database schema beyond the core, name-spaced, system tables and their default columns. The namespace is fsapi_ for system-generated tables. We recommend using a tool such as db-migrate to manage your database schema and migrations, but it’s up to you as the developer to pick a management tool you like.

Config

The config file for whatever NODE_ENV you are running, will be expected in a directory called config/ and look for a file named config.{{NODE_ENV}}.js. The config directory is expected in the same directory as your main executable file when you begin running your node process. You will likely call this file index.js or server.js.  The config file contains your API’s database connection information, server options, and a section called file_locations. File locations is important because it tells the system where to look for required static files on system boot. By default, fullyAPI expects all static json files to live in a directory called json/, located in the same directory as your main executable file.

Endpoints

There is a file called Endpoints_ext.json where you will register all of your custom API endpoints so the system knows they are available. Security.json is where you will manage the associated user roles and their access to specific endpoints, controllers, or API areas. As you register new endpoints in your extensions file, the documentation portal will reflect these changes in the endpoints section the next time you boot the system, so it is worth your time to specify your endpoints and arguments with care and helpful descriptions while you are building.

In your config file under file_locations you will see endpoints_ext as well as endpoints. endpoints_ext should contain the path for your file where you register all of your custom api endpoints. The other entry called endpoints points to the fullyAPI core endpoints specification within the node_module. Generally, you should never edit the location path for the core system endpoints file, unless you are intentionally trying to override the default available endpoints. This may be something you want to do if for instance you want to make certain default endpoints unavailable in your API. That is fine, but just remember that when you override that location, you will be responsible for tracking additions or adjustments to the available core endpoints, as your documentation will not auto-update to reflect changes in new releases, because it is not pulling data from the core module anymore.

Self-Documenting Portal: Endpoints

Models

The models file outlines the data models within your application. Registering your data models as you create tables is some extra work, yes, but it will enable you to make use of internal service functions such as updateRow() or insertRow(), and the effort you put into registering and maintaining accurate information in your Models.json file will be reflected in your self-documenting portal for other developers or members of your team.

Self-Documenting Portal: Models

API Endpoint Controller Files

An API endpoint url paths contain 4 components and are of the following structure /:areaName/:controllerName/:endpointName/:controllerVersion. This structure is a mirror of the expected directory structure of endpoint controller files within your application. API area corresponds to the directory name that contains your api controller file. Your controller file has a version indicator in the name, and contains your individual endpoints. All API area directories are expected to live in a parent directory called areas/ which is expected in the same directory as your main executable file when you begin running your node process. This keeps your root source-code directory from being cluttered if your API has many areas.

Nginx Config

If you use nginx on your server, the default api key header name contains underscores, and you will need to configure nginx to accept underscores in headers, or omit any underscores from your api key header token name. If you deploy your API and find that it is working locally but complaining of no token provided when deployed to the server — you should suspect this as the likely issue.

Services & Extensions

Similarly to endpoints, fullyAPI has several core services it uses to run, and three of those have extensions where you can add your own custom functions/methods to use throughout your application.  Extendable services include dataAccess, utilities, and accessControl. We rarely need to extend accessControl, but we use the dataAccess and utilities extensions constantly during custom development. Service extension files are expected in a services/ directory located in the same directory as your main executable file when you begin running your node process. Functions/methods in the service extension files can be accessed within your API controllers via serviceName.extension.functionName().

Postman Collections

As the developer, you may wish to make a Postman collection of API endpoints and associated environments available via your documentation portal, especially if you need to interface with a frontend team for development. The API will automatically look for a directory called postman/ in your project root and make any zip file therein named public.zip available via the portal as the postman collection download. If no collection is found in your project, the portal will fall back to the default fullyAPI postman collection provided within our npm module.

Starter Project

Below you can download a starter project that will boot once you specify the necessary database information, etc. You should use the json/ directory to find templates for all static files needed by the system. You will find a config template within the config/ directory. You will find a sample API area and controller file in the areas/ directory so you can see the expected directory structure and a sample controller file. You will find service extension file templates in the services/ directory. Check out the package on npm.

We prefer to use typescript as we like the guardrails it provides with linting and type requirements, but you can use regular nodeJS to build your API as well.

With that, go forth and build cool things. Drop us a line to let us know what you’re creating, and let us know what you think!

Share This Post

Subscribe

Join the Tech Foundry Newsletter
Tech Treats

More To Explore

Full Stack/Frontend Contract-to-hire

This position has been filled.    We are looking for an additional team member. The person we seek is intrigued by puzzles and tackling interesting

mobile-tablet-desktop-pwa
Nerd Stuff

Progressive Web Apps vs. Native Mobile

Today, we will build upon a previous post about deciding between native apps and web apps to talk specifically about the “Progressive Web App” (PWA), and how they have come into their own with iOS 16.4+.

This website uses cookies to ensure you get the best experience on our website.