Framework for build APIs using Convention Over Configuration

dev-master 2020-05-07 06:41 UTC

This package is auto-updated.

Last update: 2024-04-09 01:07:32 UTC


README

Intent

  • Create a framework base on the paradigm Convention over Configuration.
  • Create a framework that could mapping all your tables of your database into routes with a minimun effort.
  • Create a platform for create custom routes without effort

Disclaimer

First, you need to analyze your problem to solve before use this framework in order to check this documentation and check if the framework fits as a posible solution of your problem.

What you will must?

  • You must adapt you to the Frameworks' configuration.
  • You must respect the conventions' name of the clases or files for this Framework, if you don't respect them the framework couldn't works fine.
  • You must read the following documentation in order to understand the sintax, posible configurations, naming, how to set up the framework etc.
  • Your databases need to have a few characteristics in order to use the Generic habilities of the framework.

What does contain the framework?

  • Support multiple database connections
  • Expose generic CRUD REST exposing all your tables of your databases (create, get all, update, get by id, delete)
  • You could affect the lifecicle of the Generic REST with your own code
  • The generic CRUD REST has some custom configuration p.e soft delete, alter columms before update, alter columns after create, etc.
  • You could create Custom REST endpoints with your own code
  • If you put code in specific folders your code will convert into services, configuration, libraries without a piece of configuration
  • The framework support JWT for authentification linking a pivot table of your database.
  • The framework could divide your code into versions (because is an API Framework Oriented)
  • The framework has a rudimentary but effective system of migrations.
  • You could create commands by terminal (like symfony console)
  • The framework has support for documentation using swagger annotations.
  • The framework contain some example codes inside in order to show the way to use/create code inside it.
  • Support for docker, you could set up your proyect with docker and docker-compose.
  • Support for CORS.
  • Support for documentation based on Swagger.

What does not contain the framework?

  • The framework support Authentification but not for Authorization, i.e, the Framework blocks requests without a right JWT but if you have a right JWT you could access to all routes.
  • The migration system does not support rollback, only checks the collision with others sql sentences.
  • The Framework does not support big urls (please check the following tutorial for understanding that).
  • Support for background processes, the framework could create commands but not daemons, if you need that use the cron service in linux.
  • support for different databases than MySQL or PostgreSQL

Where this framework is a good idea?

  • If you need to create a big amount of CRUD endpoints with little time.
  • If you would like to create a MVP (minimun viable product) with low effort.
  • If you dont have any idea about JWT and you need to use only Authentification.
  • If you like the projects that can set up with a minimum effort.

Where this framework is a bad idea?

  • In projects where the performance is a big factor, the framework is slow for execution because the CoC.
  • In big projects is better to use a more robust frameworks like laravel, slim (without modifications like this), lumen, for the libraries, speed, community, etc.
  • If you would like to know how a Framework works (because this framework hide all these complexity).
  • If your databases do not complain the requirements of the framework because it could provoques problems with the components/configuration.
  • If your database is different than mysql or postgresql (currently the framework support only these database managers)
  • If you need a different Authentification method than JWT (this framework only supports JWT)

Tutorial

Requirements for the framework

  • PHP 7.0 or higher
  • MySQL or PostgreSQL
  • Docker
  • Docker-compose
  • composer

SETUP

Create a new Project using composer

composer create-project microservice/raptor [name_of_directory]

Configuration of the Framework

First, the framework has an example of the configuration file, please copy:

cp configuration/application.yml.example configuration/application.yml

The configuration is based on yaml format, imagine each tabulator as a point (.), p.e this:

Application:
    display_error_details: true

I will be referred as:

Application.display_error_details: true

The configurations are:

About Framework system:

Application.display_error_details: for show errors, true for show false for production

Application.add_content_length_header: always in false

Application.views.path: path where your html is (if you would like to use the templates), by default the templates are in the ./templates path

Application.logs.path: path where the application will put the messages in the log, by default the logs will be in ./logs/app.log

Application.logs.level: level for logging, the permitted values are: ERROR, DEBUG, WARN, INFO.

Application.logs.name: string that it will be showing in the logs.

Application.entity_configuration_file: for the characteristics of create CRUD on the fly the framework use this file for configurations of each table, please see the GENERIC CRUD section.

About Databases connections:

You can add multiple database connections, the main connection is named default, if you need to add another connection put the configuration under Database.connections section, the options are the following:

Database.connections.[connection_name].host: host of the database
Database.connections.[connection_name].driver: the drivers supported are **mysql** or **postgres**
Database.connections.[connection_name].database: name of the database
Database.connections.[connection_name].charset: charset of the database
Database.connections.[connection_name].username: username of the database
Database.connections.[connection_name].password: password of the database
Database.connections.[connection_name].port: port of the database
Database.connections.[connection_name].lifecycle_callbacks: these are callbacks for the custom CRUD APIs, please check the LIFECICLE CUSTOM CRUD section, for that moment delete that section.

About JWT configuration:

The framework supports JWT Authentification ,the framework only needs a connection, a pivot table (where you have the users for example), secret key, the column pivot for the table and an algorithm for the JWT, please check the JWT webpage for create a valid jwt by hand.

The options are the following:

JWT.table: the name of the table where the microservice will use in order to detect if is a valid user for the system.
JWT.connection: the principal connection where the database is (check the param Database.connections parameter).
JWT.algorithm: the algorithm wich the JWT module will based on
JWT.payload_user_field: the key of the JWT payload where the module will extract the value to search in the table.
JWT.table_user_field: the field of the table to compare with the JWT.payload_user_field value.
JWT.secret: the secret wich the module will analize if the jwt is valid.
JWT.whitelist: an array of urls wich the module will not find a valid JWT i.e, these url will not have Authorization.

Example: Imagine that you have a database named esans_prueba, the database has a table where the users are stored named usuario and it has a column named identificador:

pivot table example

In the other hand the jwt has a payload field named username something like this:

JWT example

The configuration will must be in configuration/application.yml:

Application:
    display_error_details: true
    add_content_length_header: true
    views:
        path: "/../templates/"
    logs:
        path: '/../logs/app.log'
        level: DEBUG
        name: 'API-Catalogs'
    entity_configuration_name_file: entity
Database:
    connections:
        default:
            host: localhost
            driver: mysql
            database: esans_prueba
            charset: utf8
            username: root
            password: 56974993
            port: 3306
JWT:
    table: usuario
    connection: default
    algorithm: HS512
    payload_user_field: username
    table_user_field: identificador
    secret: secretkeyforthejwtgeneration
    whitelist:
        - /hola_mundo
        - /api/docs/{version}
        - /api/documentation/{version}

With this configuration for each request the JWT module will:

  • Analize if the request contain a JWT
  • If the request contain a jwt will analyze if is a valid jwt (nbf, exp, etc. please check JWT Documentation)
  • If the JWT is valid the module get the user with the following query: *SELECT FROM usuario WHERE identificador=[jwt username key], if the user exist the user will store in the Framework container as user_claim**.

Limitations:

This version does not support soft delete in the pivot table, i.e, if you have a column active for marking inactive users the module find in all registers.

Mapping the tables to the GENERIC CRUD Module

The Framework provide us a set of commands using Silly command microframework, Jarvis PHP provide us a command for synchronize tables from the database for the GENERIC CRUD MODULE:

php scripts/jarvis.php database:schema:entity:synchronize

The sintax is:

php scripts/jarvis.php database:schema:entity:synchronize [connection_from_application_yml] [version] 

And de command will create/update the archive with the path Modules/[version]/Configuration/[entity.yml], the name of the file depends with the configuration Application.entity_configuration_name_file parameter.

Your entity file could be something like this:

entity file example

If you would like to know the different options for customizing the GENERIC CRUD urls pleasce check the sections below

And ready, we only need to turn on the microservice using docker-compose, keep in mind that you need to get the ip for the docker host (if tyou like to connect to your localhost mysql) the ip can be get with this command:

docker network inspect bridge --format='{{(index .IPAM.Config 0).Gateway}}'

And put the host ip into configuration/application.yml Database.connections section.

Check if your postgres/mysql support connections from outside before execute the docker-compose command.

If all this things are correct execute docker-compose:

docker-compose up

For check the log in real time or

docker-compose -d up

For running the microservice in silence mode.

{
    "message": "Identifier \"v1.configuration.entity\" is not defined."
}