# PostgRest: PostgreSql + API Rest ![tag](postgresql) ![tag](api) ![tag](docker) ![category](developpement) Quand on construit une application on réalise rapidement un découpage front/back. Le front communiquant via le back par des API *REST* afin d'afficher des données. Pour le back on réalise aussi rapidement un découpage - les APIs CRUD: api basique permettant de créer/modifier/supprimer des élements simples de la base de donnée - les APIs métier: embarquant une logique métier **PostgRest** se place dans la gestion des APIs CRUD afin de réaliser à partir d'une schéma d'une base de donnée postgresql l'ensemble des APIs nécessaire ![principe](./upload/postgrest.png) ## mise en oeuvre basique Pour cela nous allons tous simplement créer le fichier *docker-compose.yml* suivant ```yml version: '3' services: server: image: postgrest/postgrest ports: - "3000:3000" environment: PGRST_DB_URI: postgres://app_user:password@db:5432/app_db PGRST_DB_SCHEMA: public PGRST_DB_ANON_ROLE: app_user #In production this role should not be the same as the one used for the connection depends_on: - db db: image: postgres:11 ports: - "5432:5432" environment: POSTGRES_DB: app_db POSTGRES_USER: app_user POSTGRES_PASSWORD: password volumes: - ./db:/var/lib/postgresql/data swagger: image: swaggerapi/swagger-ui ports: - "8080:8080" expose: - "8080" environment: API_URL: http://localhost:3000/ web: image: nginx ports: - "80:80" volumes: - ./web:/usr/share/nginx/html ``` Puis nous allons lancer les commandes ```bash mkdir db mkdir web docker-compose up -d ``` Nous avons maintenant - un site web accessible sur 127.0.0.1 - un explorateur d'API swagger sur 127.0.0.1:8080 - un base postgresql sur le 127.0.0.1:5432 - un serveur d'api sur le 127.0.0.1:3000 Nous pouvons retrouver le paramétrage de *PostgRest* dans le containre sur /etc/postgrest.conf Nous allons d'abord créer une table todos contenant une liste de todo ```sql create table todos ( id serial primary key, done boolean not null default false, task text not null, due timestamptz ); insert into todos (task) values ('finish tutorial 0'), ('pat self on back'); ``` ```note vous pouvez utiliser *pgcli* pour faire cela via la connexion "pgcli -h 127.0.0.1 -p 5432 -W app_db app_user" ``` Si vous allez sur http://127.0.0.1:3000 vous pouvez - via le **GET** voir les todos - via le **POST** ajouter les todos - via le **DELETE** supprimer *tous* les todos - via le **PATCH** avec une return *none* modifier un todo Si vous ajouter dans le repertoire web un fichier *index.html* contenant ```html ``` Vous pouvez consulter la liste des todos sur http://127.0.0.1// ## Gestion des droits La gestion des droits ce fait par l'usage d'un schema. En effet dans le fichier postgrest.conf on specifie l'usage - l'usage d'un schema PGRST_DB_SCHEMA - d'un rôle PGRST_DB_ANON_ROLE: On peut au niveau postgresql spécifier pour un schéma/un role des droits de select/insert ... Par exemple si on lance sur la base ```sql create role web_anon nologin; grant usage on schema api to web_anon; grant select on api.todos to web_anon; ``` Nous créons ainsi le rôle web_anon (qui ne peut se connecter directement ... on ne pourra utiliser ce rôle comme un utilisateur de la base postgres). Nous indiquons par la suite que ce rôle est autorisé à utilisé le schéma api (qu'il faudra au préalable créer ou utiliser le schéma par defaut *public*). L'utilisateur qui se connectera avec un utilisateur de la base et ce role web_anon ne pourra que faire du select sur la table api.todos. Nous gérons les droits au niveau de la base toujours pas au niveau de la connexion du serveur **PostgRest**: tous le monde peut utiliser l'ensemble des APIs. **PostgRest** propose l'usage de token jwt ... je pense qu'on peut aussi gérer cela à un niveau plus haut, par l'usage d'un *kong* par exemple. ## A faire - voir comment on gère l'authentification par jeton - voir comment on supprime qu'une ligne Allez voir l'url https://g-ernaelsten.developpez.com/tutoriels/PostgREST/ qui explicite aussi ces éléments