OpenAPI

Pour faciliter l’interfacage applicatif, SAINet fournit un descripteur OpenAPI. Ce descripteur peut ensuite être utilisé par des outils génériques (postman, swagger, …) afin de créer les différents objets pouvant être ®envoyés par SAINet.

Note:

Étant donné le grand nombre de tâches, il y a un descripteur OpenAPI par tâche. Celui-ci peut potentiellement être différent par domaine.

Récupérer un descripteur

Il n’est pas obligatoire d’avoir effectué un login pour récupérer le descripteur, mais il est nécessaire d’avoir un compte utilisateur dans SAINet.

La commande est la suivante:

curl --insecure --silent \
     'https://<host>/SNV4SRV-ws-war/api/v1/<task>/$openapi?user=<username>&password=<password>&domainId=<domain>'
Info:

L’URL peut être directement utilisée dans un navigateur web.

Il est également possible d’utiliser une authentification Basic (avec un header Authorization). Lorsque c’est le cas, les paramètres user et password ne doivent pas être spécifiés dans l’URL.

En cas de succès, un descripteur OpenAPI est retourné:

{
  "openapi": "3.1.0",
  "info": {
    "title": "SAINet V4 API",
    "version": "4.10.14",
    "description": "...",
    "summary": "..."
  },
  ...
}

Celui-ci peut ensuite être utilisé dans des outils en ligne (tels que swagger) afin de voir comment les requêtes doivent être adressées et quelles sont les données retournées par SAINet.

Exemple

Ci-dessous, un exemple de requête pour obtenir le descripteur (authentification Basic):

curl --insecure --silent \
     --user <user>:<password> \
     'https://<host>/SNV4SRV-ws-war/api/v1/GTP40/$openapi?&domainId=<domain>'
Voir le descripteur OpenAPI
{
  "openapi": "3.1.0",
  "info": {
    "title": "SAINet V4 API",
    "version": "4.11.0-20230324-094622",
    "description": "GTP40 - Planning",
    "summary": "Evénements"
  },
  "servers": [
    {
      "url": "https://localhost:9191/SNV4SRV-ws-war/api/{basePath}",
      "description": "NA (MASTER)",
      "variables": {
        "basePath": {
          "default": "v1"
        }
      }
    }
  ],
  "paths": {
    "/login": {
      "get": {
        "operationId": "login",
        "parameters": [
          {
            "name": "user",
            "description": "Nom d'utilisateur (obligatoire si une authentification Basic n'est pas utilisée)",
            "in": "query",
            "required": false,
            "allowEmptyValue": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "password",
            "description": "Mot de passe (obligatoire si une authentification Basic n'est pas utilisée)",
            "in": "query",
            "required": false,
            "allowEmptyValue": false,
            "schema": {
              "type": "string",
              "format": "password"
            }
          },
          {
            "name": "domainId",
            "description": "Identifiant du domaine",
            "in": "query",
            "required": true,
            "allowEmptyValue": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Authentification BASIC pour obtenir un token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            },
            "headers": {
              "Sai-Server-Instance": {
                "description": "Identifiant de l'instance SAINet (à insérer dans tous les appels en cas de multi-instances)",
                "schema": {
                  "type": "string"
                }
              },
              "Sai-Bearer-Token": {
                "description": "Token à utiliser pour les appels à l'API",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide"
          },
          "401": {
            "description": "Accès non autorisé"
          },
          "403": {
            "description": "L'API n'est pas activée"
          },
          "405": {
            "description": "Méthode HTTP invalide"
          },
          "406": {
            "description": "Erreur durant le traitement de la requête",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/business-failure"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne"
          }
        },
        "security": [
          {},
          {
            "sai-basic": []
          }
        ]
      }
    },
    "/GTP40": {
      "get": {
        "operationId": "listGTP40Records",
        "parameters": [
          {
            "name": "page",
            "description": "Numéro de la page à récupérer (par défaut 1)",
            "in": "query",
            "required": false,
            "allowEmptyValue": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "limit",
            "description": "Nombre d'enregistrements par page (par défaut 20)",
            "in": "query",
            "required": false,
            "allowEmptyValue": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "filter",
            "description": "Filtre sur les enregistrements",
            "in": "query",
            "required": false,
            "allowEmptyValue": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste des enregistrements (limité à 20 par défaut)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/gtp40-list"
                  }
                }
              }
            },
            "headers": {
              "Sai-Server-Instance": {
                "description": "Identifiant de l'instance SAINet (à insérer dans tous les appels en cas de multi-instances)",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide"
          },
          "401": {
            "description": "Accès non autorisé"
          },
          "403": {
            "description": "L'API n'est pas activée"
          },
          "405": {
            "description": "Méthode HTTP invalide"
          },
          "406": {
            "description": "Erreur durant le traitement de la requête",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/business-failure"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne"
          }
        },
        "security": [
          {
            "sai-bearer": []
          }
        ]
      }
    },
    "/GTP40/{recordId}": {
      "get": {
        "operationId": "getGTP40Record",
        "parameters": [
          {
            "name": "recordId",
            "description": "Identifiant de l'enregistrement",
            "in": "path",
            "required": true,
            "allowEmptyValue": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Accès à un enregistrement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/gtp40-record"
                }
              }
            },
            "headers": {
              "Sai-Server-Instance": {
                "description": "Identifiant de l'instance SAINet (à insérer dans tous les appels en cas de multi-instances)",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide"
          },
          "401": {
            "description": "Accès non autorisé"
          },
          "403": {
            "description": "L'API n'est pas activée"
          },
          "405": {
            "description": "Méthode HTTP invalide"
          },
          "406": {
            "description": "Erreur durant le traitement de la requête",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/business-failure"
                }
              }
            }
          },
          "500": {
            "description": "Erreur interne"
          }
        },
        "security": [
          {
            "sai-bearer": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "global-metadata": {
        "type": "object",
        "properties": {
          "apiVersion": {
            "type": "string"
          },
          "taskId": {
            "type": "string"
          },
          "taskType": {
            "type": "string",
            "enum": [
              "R",
              "B"
            ]
          },
          "domainId": {
            "type": "string"
          }
        }
      },
      "business-failure": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "SUCCESS",
              "FAILURE",
              "ONGOING"
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "INVALID_INPUT",
              "SYSTEM_FAILURE",
              "CORRUPTED_DATA",
              "BUSINESS_FAILURE",
              "COMMENT",
              "PASSWORD_EXPIRED"
            ]
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "enum-gtpevt.isvalidated": {
        "type": "object",
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "1"
              },
              "value": {
                "type": "string",
                "const": "Pas encore regardé"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "2"
              },
              "value": {
                "type": "string",
                "const": "Finalisé par MSP ou RS"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "3"
              },
              "value": {
                "type": "string",
                "const": "Finalisé par administrateur"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "9"
              },
              "value": {
                "type": "string",
                "const": "Rejeté par administrateur"
              }
            }
          }
        ]
      },
      "enum-gtpevt.pertype": {
        "type": "object",
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "1"
              },
              "value": {
                "type": "string",
                "const": "Aucune"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "2"
              },
              "value": {
                "type": "string",
                "const": "Hebdomadaire"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "3"
              },
              "value": {
                "type": "string",
                "const": "Mensuelle"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "4"
              },
              "value": {
                "type": "string",
                "const": "Annuelle"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "5"
              },
              "value": {
                "type": "string",
                "const": "Toutes les 2 semaines"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "6"
              },
              "value": {
                "type": "string",
                "const": "Toutes les 3 semaines"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "7"
              },
              "value": {
                "type": "string",
                "const": "Toutes les 4 semaines"
              }
            }
          }
        ]
      },
      "enum-gtpevt.realized": {
        "type": "object",
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "1"
              },
              "value": {
                "type": "string",
                "const": "Planifié seulement"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "2"
              },
              "value": {
                "type": "string",
                "const": "Planifié et réalisé"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "3"
              },
              "value": {
                "type": "string",
                "const": "Réel seulement"
              }
            }
          }
        ]
      },
      "enum-gtp_priority": {
        "type": "object",
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "1"
              },
              "value": {
                "type": "string",
                "const": "Faible"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "2"
              },
              "value": {
                "type": "string",
                "const": "Normal (Evénement généré)"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "3"
              },
              "value": {
                "type": "string",
                "const": "Normal (Saisie manuelle)"
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "const": "4"
              },
              "value": {
                "type": "string",
                "const": "Prioritaire (Correction pour décompte)"
              }
            }
          }
        ]
      },
      "gtp40-list": {
        "type": "object",
        "properties": {
          "metadata": {
            "$ref": "#/components/schemas/global-metadata"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/gtp40-record-simple"
            }
          }
        }
      },
      "gtp40-record-simple": {
        "type": "object",
        "properties": {
          "$recordId": {
            "summary": "Identifiant de l'enregistrement",
            "type": "string"
          },
          "STRUCTURE": {
            "summary": "Structure",
            "type": "string"
          },
          "STRUCTURELABEL": {
            "summary": "Nom",
            "type": "string"
          },
          "COLLABORATEUR": {
            "summary": "Collaborateur",
            "type": "string"
          },
          "COLLABORATEURLABEL": {
            "summary": "Nom",
            "type": "string"
          },
          "DOSSIER": {
            "summary": "Dossier",
            "type": "string"
          },
          "DOSSIERLABEL": {
            "summary": "Nom du dossier",
            "type": "string"
          },
          "HORAIRE": {
            "summary": "Connexion calendrier",
            "type": "string"
          },
          "HORAIRELABEL": {
            "summary": "Libellé",
            "type": "string"
          },
          "NO_RECO": {
            "summary": "No événement",
            "type": "string"
          },
          "LABEL": {
            "summary": "Libellé",
            "type": "string"
          },
          "DEBUT": {
            "summary": "Début",
            "type": "string",
            "format": "date-time"
          },
          "FIN": {
            "summary": "Fin",
            "type": "string",
            "format": "date-time"
          },
          "COMMENTARY": {
            "summary": "Commentaire",
            "type": "string"
          },
          "EVENT": {
            "summary": "Créer un événement (ADR40)",
            "type": "boolean"
          },
          "REALIZED": {
            "summary": "Réalisé",
            "$ref": "#/components/schemas/enum-gtpevt.realized"
          },
          "TYPE": {
            "summary": "Type",
            "type": "string"
          },
          "TYPELABEL": {
            "summary": "Libellé",
            "type": "string"
          },
          "ISVALIDATED": {
            "summary": "Validé",
            "$ref": "#/components/schemas/enum-gtpevt.isvalidated"
          },
          "PRIORITY": {
            "summary": "Priorité",
            "$ref": "#/components/schemas/enum-gtp_priority"
          },
          "EXCHANGE_ID": {
            "summary": "Indique si l'événement est synchronisé avec exchange",
            "type": "string"
          },
          "FE": {
            "summary": "Finaliser",
            "type": "string"
          },
          "SYNCH_WITH_EXCHANGE": {
            "summary": "Synchroniser avec Exchange (Outlook)",
            "type": "boolean"
          },
          "SEND_EXCHANGE_INVITATIONS": {
            "summary": "Invités (emails)",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "EVTID": {
            "summary": "No événement",
            "type": "string"
          },
          "PERGID": {
            "summary": "Id de la série",
            "type": "integer"
          },
          "PERWREC": {
            "summary": "Toutes les (n) semaines",
            "type": "integer"
          },
          "PERTYP": {
            "summary": "Type de périodicité",
            "$ref": "#/components/schemas/enum-gtpevt.pertype"
          },
          "PEREND": {
            "summary": "Date de fin de la récurrence",
            "type": "string",
            "format": "date-time"
          },
          "PERWMON": {
            "summary": "Lundi",
            "type": "boolean"
          },
          "PERWTUE": {
            "summary": "Mardi",
            "type": "boolean"
          },
          "PERWWED": {
            "summary": "Mercredi",
            "type": "boolean"
          },
          "PERWTHU": {
            "summary": "Jeudi",
            "type": "boolean"
          },
          "PERWFRI": {
            "summary": "Vendredi",
            "type": "boolean"
          },
          "PERWSAT": {
            "summary": "Samedi",
            "type": "boolean"
          },
          "PERWSUN": {
            "summary": "Dimanche",
            "type": "boolean"
          },
          "HOLIDAYS": {
            "summary": "Tenir compte des jours fériés",
            "type": "boolean"
          }
        }
      },
      "gtp40-record": {
        "type": "object",
        "properties": {
          "metadata": {
            "$ref": "#/components/schemas/global-metadata"
          },
          "data": {
            "$ref": "#/components/schemas/gtp40-record-simple"
          }
        }
      }
    },
    "securitySchemes": {
      "sai-bearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "sai-basic": {
        "type": "http",
        "scheme": "basic"
      }
    }
  },
  "externalDocs": {
    "description": "SAINet API documentation",
    "url": "https://doc.sai-erp.net/030_doc_api.html"
  }
}