Remarques sur *l'implémentation*, explication de choix de design...

Pour des commentaires sur la définition du schéma, se reporter plutôt aux commentaires en en-tête des fichiers `actions.graphql` et `objects.graphql`.

Pour des explications plus high-level sur la gestion des droits et les authorizations sur Sigma, voir le memo idoine {@tutorial hist_rights}.

## Structure du dossier `src/graphql`

```bash
graphql
├── models
│   ├── authorization.ts
│   ├── groupModel.ts
│   ├── messageModel.ts
│   ├── requestModel.ts
│   ├── tools.ts
│   └── userModel.ts
├── object_resolvers
│   ├── groups.ts
│   ├── messages.ts
│   ├── requests.ts
│   └── users.ts
├── resolvers.ts
├── schema.js
└── typeDefs
    ├── actions.graphql
    ├── objects.graphql
    └── queries.d.ts
```

Les sections suivantes expliqueront la logique des models et object_resolvers ; pour l'instant,expliquons quelques points simples. 

### "Points d'entrée"
`graphql/schema.js` exporte tout le schéma GraphQL, utilisé pour configurer ApolloServer dans `app.ts`. 

A la réception d'une requête GraphQL, avant de la resolver, une instance de chaque object model de `graphql/models/` est créée, et passée dans le context. Ceci est aussi effectué dans `app.ts` (`const context = ...`).

### La définition du schéma : `src/graphql/typeDefs`

C'est assez straightforward quand on connaît les bases de GraphQL... 

`queries.d.ts` définit l'interface Typescript `Context`.

### Export des resolvers `graphql/resolvers.ts`

Du point de vue de `graphql/schema.js`, qui les importe, le fichier `graphql/resolvers.ts` exporte bien tous les resolvers de tous les types du schéma GraphQL.
Pourtant, on ne définit dans `graphql/resolvers.ts` que les resolvers pour les types Query et Mutations. 
En effet on exploite les default resolvers fournis par Apollo Server (le deuxième point) :

> Explicit resolvers are not needed for every type, since Apollo Server provides a default that can perform two actions depending on the contents of parent:
> - Return the property from parent with the relevant field name
> - Calls a function on parent with the relevant field name and provide the remaining resolver parameters as arguments
https://www.apollographql.com/docs/apollo-server/v2/essentials/data.html#default

Dans notre cas, le type de retour de chaque resolver est un objet JS (Group, Message, Request ou User) défini dans un des fichiers de `graphql/object_resolvers/` ; donc les méthodes des classes Group, Message, Request et User dont le prototype est (parent, args, context: Context, info) sont utilisées comme resolvers de l'objet GraphQL respectif.

(Les sections suivantes donnent plus de précisions sur la logique derrière ce dernier paragraphe.)


## Resolvers/Models/Connectors

Les notions de models et de connectors sont assez communes en développement web. Une définition informelle appliquée au contexte de GraphQL est donnée ici :

https://blog.apollographql.com/how-to-build-graphql-servers-87587591ded5
> Model: a set of functions to read/write data of a certain GraphQL type by using various connectors. Models contain additional business logic, such as permission checks, and are usually application-specific.

> Connector: a layer on top of a database/backend driver that has GraphQL-specific error handling, logging, caching and batching. Only needs to be implemented once for each backend, and can be reused in many apps

> By using models and connectors, my resolvers turned into simple switches that map inputs and arguments to a function call in the underlying model layer, where the actual business logic resides.

> Note: To be clear, models and connectors aren’t abstractions that are built into GraphQL, but they emerge as a natural way to structure code in a GraphQL server.

### Connectors

Dans notre cas, on utilise à la fois une base de données propre à Sigma (PostgreSQL, manipulée avec Knexjs) et un LDAP (manipulé avec les fonctions de `src/ldap/export/`, développées par Quentin Chevalier, qu'il appelle son "API LDAP").

Knexjs et l'"API LDAP" sont les équivalents des Connectors pour notre projet. Pas besoin de se forcer à faire une couche supplémentaire, ça ne serait pas utile.


### Les resolvers des actions : `graphql/resolvers.ts`

### Les resolvers des objets : `graphql/object_resolvers/`

Les classes JS définies dans les fichiers de `graphql/object_resolvers/` jouent à la fois le rôle de resolvers (plus précisément, ont des méthodes qui sont utilisées comme resolvers), et de return type pour les resolvers. 
C'est ceci qui permet d'exploiter à fond les defaults resolvers d'Apollo Server.

Une bonne façon de le voir est de dire que :
- du point de vue de l'export du schéma (donc de `schema.js` et `resolvers.ts`), ces fichiers servent à définir les resolvers, tout simplement
- du point de vue des autres fichiers qui les importent, ces fichiers définissent des return types de resolvers.

### Models : `graphql/models`

Comme indiqué plus haut, une instance de chaque object model est créée et passée dans le context, à chaque réception d'une requête GraphQL. En fait, puisque les constructeurs ne prennent en paramètre que l'uid de l'utilisateur qui fait la requête, on peut dire qu'un set de models est créé pour chaque utilisateur.

Autrement dit, chaque utilisateur a ses propres "data accessors", sa propre "vue" de la BDD, personnalisée pour prendre en compte ses memberOfs.



## Implémentation de la gestion des authorizations

En anglais, authori*s*ation est une orthographe valide, mais pour plus d'homogénéité et pour reprendre l'usage habituel sur internet, on utilisera l'orthographe américaine authori*z*ation.

Comme déjà indiqué plus haut, pour des explications plus high-level sur la gestion des droits et les authorizations sur Sigma, voir le memo idoine (`memo_sigma_rights.md`).

### authorization.ts