This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
LLMApi: gRPC Mock API Support avec les tampons protocoles
Thursday, 06 November 2025
Introduction
Il s'agit de la documentation pour le support gRPC Mock API dans LLMApi.
NOTE: Il s'agit du live de GitHub. Il est généré par l'AIM SK2
Vous pouvez trouver le GitHub ici pour le projet, tous les domaines publics, etc.
gRPC Mock API Support avec les tampons protocoles
LLMock API fournit maintenant un support gRPC complet, vous permet de reproduire les services gR PC dynamiquement sans avoir à écrire aucune mise en œuvre de service. chargez votre .proto les fichiers, et le serveur témoin gère le reste - générant des réponses réalistes basées sur vos définitions de message Protobuf
Vue d'ensemble
La fonction gRPC appuie deux approches complémentaires:
- JSON sur HTTP - Perfect pour le navigateur- basé sur l'essai et la mise au point rapide de prototypes
- Les tampons du protocole binaire - Autre protocole de câble gRPC pour la production-essais similaires à ceux effectués avec des clients gR PC réels
Les deux approches utilisent le même fichier téléchargé .proto définitions et LLM-réponses générées
graph TD
A[Upload .proto File] --> B[Proto Parser]
B --> C[Service Definitions Stored]
C --> D{Client Request Type?}
D -->|JSON| E[JSON Endpoint]
D -->|Binary Protobuf| F[Binary Endpoint]
E --> G[LLM Generates Response]
F --> G
G --> H{Output Format?}
H -->|JSON| I[Return JSON]
H -->|Binary| J[Serialize to Protobuf]
J --> K[Return Binary Response]
Démarrage rapide
1. Télécharger un fichier proto
Premièrement, définissez votre service gRPC dans un .proto fichier:
syntax = "proto3";
package userservice;
service UserService {
rpc GetUser (GetUserRequest) returns (User);
rpc ListUsers (ListUsersRequest) returns (UserList);
rpc CreateUser (CreateUserRequest) returns (User);
}
message GetUserRequest {
int32 user_id = 1;
}
message ListUsersRequest {
int32 page = 1;
int32 page_size = 2;
optional string filter = 3;
}
message CreateUserRequest {
string name = 1;
string email = 2;
optional string phone = 3;
}
message User {
int32 id = 1;
string name = 2;
string email = 3;
optional string phone = 4;
string created_at = 5;
bool is_active = 6;
}
message UserList {
repeated User users = 1;
int32 total_count = 2;
int32 page = 3;
}
Soumettre ce fichier proto au serveur modèle:
# Upload via plain text body
curl -X POST http://localhost:5116/api/grpc-protos \
-H "Content-Type: text/plain" \
--data-binary "@user_service.proto"
# Or upload as multipart form
curl -X POST http://localhost:5116/api/grpc-protos \
-F "file=@user_service.proto"
La réponse montre votre structure de service:
{
"message": "Proto definition uploaded successfully",
"name": "user_service.proto",
"package": "userservice",
"services": [
{
"name": "UserService",
"methods": [
{
"name": "GetUser",
"type": "Unary",
"input": "GetUserRequest",
"output": "User"
},
{
"name": "ListUsers",
"type": "Unary",
"input": "ListUsersRequest",
"output": "UserList"
},
{
"name": "CreateUser",
"type": "Unary",
"input": "CreateUserRequest",
"output": "User"
}
]
}
]
}
2. Méthodes d'appel - JSON sur HTTP
Pour l’essai rapide et le navigateur, les clients fondés sur -, utilisent les points de fin JSON:
# Get a user (JSON request/response)
curl -X POST http://localhost:5116/api/grpc/UserService/GetUser \
-H "Content-Type: application/json" \
-d '{"user_id": 12345}'
Le LLM génère une réponse réaliste correspondant à votre définition proto:
{
"id": 12345,
"name": "Sarah Chen",
"email": "[email protected]",
"phone": "+1-555-0142",
"created_at": "2024-03-15T10:30:00Z",
"is_active": true
}
3. Méthodes d'appel - Buffers du protocole binaire
Pour la production-essais similaires à ceux effectués avec le protocole de câble gRPC réel:
# Create a binary Protobuf request (example using protoc)
echo '{"user_id": 12345}' | \
protoc --encode=userservice.GetUserRequest user_service.proto > request.bin
# Send binary request, get binary response
curl -X POST http://localhost:5116/api/grpc/proto/UserService/GetUser \
-H "Content-Type: application/grpc+proto" \
--data-binary "@request.bin" \
--output response.bin
# Decode binary response
protoc --decode=userservice.User user_service.proto < response.bin
Output:
id: 12345
name: "Sarah Chen"
email: "[email protected]"
phone: "+1-555-0142"
created_at: "2024-03-15T10:30:00Z"
is_active: true
Comment cela fonctionne
Partage de fichiers proto
Lorsque vous téléchargez un .proto file, le serveur de simulation l'analyse pour extraire
- Définitions des services
- Signatures de méthode RPC
- Définitions du type de message
- Types et numéros de champ
sequenceDiagram
participant Client
participant ProtoManager
participant ProtoParser
participant Storage
Client->>ProtoManager: Upload user_service.proto
ProtoManager->>ProtoParser: Parse(content)
ProtoParser->>ProtoParser: Extract syntax/package
ProtoParser->>ProtoParser: Parse services
ProtoParser->>ProtoParser: Parse messages
ProtoParser->>ProtoManager: Return ProtoDefinition
ProtoManager->>Storage: Store in ConcurrentDictionary
ProtoManager->>Client: Return success + metadata
Le parteur utilise une extraction basée sur regex- pour identifier les éléments proto:
// Service extraction
var serviceRegex = new Regex(
@"service\s+([a-zA-Z0-9_]+)\s*\{([^}]+)\}",
RegexOptions.Singleline);
// Method extraction
var methodRegex = new Regex(
@"rpc\s+([a-zA-Z0-9_]+)\s*\(\s*(stream\s+)?([a-zA-Z0-9_.]+)\s*\)" +
@"\s*returns\s*\(\s*(stream\s+)?([a-zA-Z0-9_.]+)\s*\)");
// Message extraction
var messageRegex = new Regex(
@"message\s+([a-zA-Z0-9_]+)\s*\{([^}]+)\}",
RegexOptions.Singleline);
Request Handling Flow
Points finals de JSON
sequenceDiagram
participant Client
participant Endpoint
participant GrpcHandler
participant ProtoManager
participant LLM
Client->>Endpoint: POST /api/grpc/UserService/GetUser<br/>(JSON body)
Endpoint->>ProtoManager: FindMethod(UserService, GetUser)
ProtoManager->>Endpoint: Return method definition
Endpoint->>GrpcHandler: HandleUnaryCall(service, method, json)
GrpcHandler->>ProtoManager: GetMessage(User)
ProtoManager->>GrpcHandler: Return message schema
GrpcHandler->>GrpcHandler: Build LLM prompt with schema
GrpcHandler->>LLM: Generate response for User message
LLM->>GrpcHandler: Return JSON response
GrpcHandler->>Endpoint: Extract and return JSON
Endpoint->>Client: JSON response
Le gestionnaire construit un prompt détaillé pour le LLM:
var prompt = $@"You are a gRPC service mock. Generate realistic data for this response.
Service: {serviceName}
Method: {methodName}
Request: {requestJson}
Generate a response matching this structure:
{jsonShape}
Return ONLY valid JSON matching the structure above. Be creative with realistic values.";
Paramètres finales du protobuf binaire
sequenceDiagram
participant Client
participant Endpoint
participant GrpcHandler
participant ProtobufHandler
participant LLM
Client->>Endpoint: POST /api/grpc/proto/UserService/GetUser<br/>(Binary Protobuf)
Endpoint->>GrpcHandler: HandleUnaryCallBinary(service, method, bytes)
GrpcHandler->>ProtobufHandler: CreateJsonTemplate(inputMessage)
ProtobufHandler->>GrpcHandler: Return JSON template
GrpcHandler->>LLM: Generate response (same as JSON flow)
LLM->>GrpcHandler: Return JSON response
GrpcHandler->>ProtobufHandler: SerializeFromJson(json, outputMessage)
ProtobufHandler->>ProtobufHandler: Write Protobuf binary format
ProtobufHandler->>GrpcHandler: Return binary bytes
GrpcHandler->>Endpoint: Return binary Protobuf
Endpoint->>Client: Binary response (application/grpc+proto)
Serialisation des tampons de protocole
L'article 5 de la Loi sur l'immigration et le statut des réfugiés DynamicProtobufHandler convert JSON en format protobuf binaire à l'aide de définitions de champ:
public byte[] SerializeFromJson(
string json,
ProtoMessage messageDefinition,
List<ProtoMessage> allMessages)
{
var jsonDoc = JsonDocument.Parse(json);
using var stream = new MemoryStream();
using var writer = new CodedOutputStream(stream);
// Write each field according to proto definition
foreach (var field in messageDefinition.Fields.OrderBy(f => f.Number))
{
if (!jsonDoc.RootElement.TryGetProperty(field.Name, out var fieldValue))
continue; // Skip missing fields
WriteField(writer, field, fieldValue, allMessages);
}
writer.Flush();
return stream.ToArray();
}
Les types de fil sont déterminés par le type de champ:
private WireFormat.WireType GetWireType(string fieldType)
{
return fieldType switch
{
"string" or "bytes" => WireFormat.WireType.LengthDelimited,
"int32" or "int64" or "uint32" or "uint64" or
"sint32" or "sint64" or "bool" => WireFormat.WireType.Varint,
"fixed32" or "sfixed32" or "float" => WireFormat.WireType.Fixed32,
"fixed64" or "sfixed64" or "double" => WireFormat.WireType.Fixed64,
_ => WireFormat.WireType.LengthDelimited // Complex/nested types
};
}
API de gestion
La fonctionnalité gRPC comprend une API de gestion complète pour travailler avec les définitions proto:
Liste de tous les protos
curl http://localhost:5116/api/grpc-protos
Réponse:
{
"definitions": [
{
"name": "user_service.proto",
"package": "userservice",
"syntax": "proto3",
"uploadedAt": "2025-01-05T20:30:00Z",
"serviceCount": 1,
"messageCount": 5,
"services": ["UserService"]
}
],
"count": 1
}
Obtenir des détails sur le prototype
curl http://localhost:5116/api/grpc-protos/user_service.proto
Retourne tous les détails, y compris tous les services, méthodes, messagesM SK2 et définitions de champs .
Supprimer le prototype
curl -X DELETE http://localhost:5116/api/grpc-protos/user_service.proto
Supprimer tous les protos
curl -X DELETE http://localhost:5116/api/grpc-protos
API Endpoints Référence
Points finals de la gestion proto
| Méthode MSC1 Point final MSC2 Description SMC3 | ||
|---|---|---|
POST |
/api/grpc-protos |
Télécharger un fichier de protocole .(formulaire simple ou multipartite |
GET |
/api/grpc-protos |
Liste de toutes les définitions proto téléchargées |
GET |
/api/grpc-protos/{name} |
Obtenir les détails d'un proto spécifique |
DELETE |
/api/grpc-protos/{name} |
Supprimer une définition de proto spécifique |
DELETE |
/api/grpc-protos |
Supprimer toutes les définitions proto |
gRPC Service Call Endpoints
| Méthode MSC1 Point final MSC2 Description SMC3 | ||
|---|---|---|
POST |
/api/grpc/{service}/{method} |
Invoquer la méthode avec une demande JSON/réponse |
POST |
/api/grpc/proto/{service}/{method} |
Invoquer la méthode avec une demande de Protobuf binaire/réponse |
Exemples avancés
Messages insérés complexes
syntax = "proto3";
package orderservice;
service OrderService {
rpc CreateOrder (OrderRequest) returns (Order);
}
message OrderRequest {
string customer_id = 1;
repeated OrderItem items = 2;
Address shipping_address = 3;
PaymentInfo payment = 4;
}
message OrderItem {
string product_id = 1;
int32 quantity = 2;
double unit_price = 3;
}
message Address {
string street = 1;
string city = 2;
string state = 3;
string postal_code = 4;
string country = 5;
}
message PaymentInfo {
string method = 1;
string last_four_digits = 2;
}
message Order {
string order_id = 1;
string customer_id = 2;
repeated OrderItem items = 3;
Address shipping_address = 4;
string status = 5;
double total_amount = 6;
string created_at = 7;
}
Demander avec JSON ensemencée:
curl -X POST http://localhost:5116/api/grpc/OrderService/CreateOrder \
-H "Content-Type: application/json" \
-d '{
"customer_id": "CUST-12345",
"items": [
{
"product_id": "PROD-001",
"quantity": 2,
"unit_price": 29.99
},
{
"product_id": "PROD-042",
"quantity": 1,
"unit_price": 149.99
}
],
"shipping_address": {
"street": "123 Main Street",
"city": "San Francisco",
"state": "CA",
"postal_code": "94102",
"country": "USA"
},
"payment": {
"method": "credit_card",
"last_four_digits": "4242"
}
}'
Le LLM génère une réponse d'ordre réaliste avec tous les champs entamés..
Champs et tableaux répétés
Le proto-parser gère automatiquement les champs répétés:
message ProductList {
repeated Product products = 1;
int32 total_count = 2;
}
message Product {
string id = 1;
string name = 2;
double price = 3;
repeated string tags = 4;
}
Réponse avec plusieurs tableaux nested:
{
"products": [
{
"id": "PROD-001",
"name": "Wireless Mouse",
"price": 29.99,
"tags": ["electronics", "peripherals", "wireless"]
},
{
"id": "PROD-002",
"name": "Mechanical Keyboard",
"price": 149.99,
"tags": ["electronics", "peripherals", "gaming"]
}
],
"total_count": 47
}
Configuration
Ajouter le support gRPC à votre application ASP.NET Core:
using mostlylucid.mockllmapi;
var builder = WebApplication.CreateBuilder(args);
// Add LLMock API services (includes gRPC)
builder.Services.AddLLMockApi(builder.Configuration);
var app = builder.Build();
// Map proto management endpoints
app.MapLLMockGrpcManagement("/api/grpc-protos");
// Map gRPC service call endpoints (both JSON and binary)
app.MapLLMockGrpc("/api/grpc");
app.Run();
L'article 5 de la Loi sur l'immigration et le statut des réfugiés AddLLMockApi() la méthode enregistre automatiquement:
ProtoDefinitionManager- Génie les définitions proto téléchargéesProtoParser- Parse les fichiers de protocole .DynamicProtobufHandler- Génie la serialisation du protobuf binaireGrpcRequestHandler- Processue les appels de méthode gRPC
Limites actuelles
Des appels uniques seulement
La mise en œuvre actuelle appuie appels uniques RPC seulement (requête simpleM SK1réponse ). Les méthodes de radiodiffusion sont analysées mais n'ont pas encore été mises en œuvre
service DataService {
// Supported
rpc GetData (Request) returns (Response);
// Not yet supported
rpc StreamData (Request) returns (stream Response);
rpc UploadData (stream Request) returns (Response);
rpc BidirectionalStream (stream Request) returns (stream Response);
}
Tenter d'appeler une méthode de diffusion retourne un erreur:
{
"error": "Method StreamData is not a unary call. Type: ServerStreaming"
}
Partage simplifié de Protobuf
La mise en œuvre du protobuf binaire est simplifiée:
Demande d'analyse: Utilise actuellement un modèle JSON plutôt qu’à analyser la demande de Protobuf binaire réelle.
Réponse à la serialisation: Serialise correctement JSON au format protobuf binaire selon les types de fil et les numéros de champ.
L’analyse complète des demandes nécessiterait une complexité supplémentaire pour traiter les variables-encodage de longueurM SK1 messages ensemblés , et proto3 par défautMSC4
Soutien du format de fichier Proto
Le parteur appuie les caractéristiques communes du proto3 mais a des limites:
Soutenu:
- Types de champs fondamentaux (stringM SK1 int32,int 64, uintMNK4 uinteMKK5 boulMKS6 floatM KS7 doubleM SS8 bytesMSS9
- Champs répétés
- Champs facultatifs
- Messages nichés
- Services avec des méthodes uniques
Non supporté:
- Enums (parsés mais non validés)
- Cartes (pas encore mise en œuvre)
- Un (non analyséM SK1
- Extensions (non parlée)
- Options et annotations (ignoré)
- Importation des déclarations (non résolueM SK1
Réfléction du serveur gRPC (En cours)
Les clients gRPC standard s'attendent à ce que les serveurs appuient Protocole de réflexion du serveur gRPC.
État actuel:
- Infrastructure de réflexion mise en place à l'aide d'une
protobuf-net.Reflection(vM SK1 - Les fichiers Proto sont compilés à
FileDescriptorSetlorsque téléchargé GrpcReflectionServicestocke et gère les descripteurs compilés- Intégration avec
ProtoDefinitionManagerintégralité
Ce qui fonctionne:
- Compilation proto dynamique: Uploaded
.protoLes fichiers sont analysés et compilés au moment du démarrage - Entreposage de déscripteurs: Les objets FileDescriptorSet sont générés et cachés
- API de gestion:
GET /api/grpc-protosliste tous les fichiers proto téléchargés avec des détails complets - JSON endpoint: Détection et essais complets du service via HTTP/JSON
- Page de démonstration: Interactive UI montre tous les services et méthodes disponibles
Qu’est-ce qui se passe?
- Mapping standard du point final de réflexion gRPC (
grpc.reflection.v1alpha.ServerReflectionservice) - Intégration complète de grpcurl sans exiger
-protoIl s’agit d’une opération qui a été menée à bien dans le cadre de l’accord conclu entre les deux parties.
Application technique:
Lorsque vous téléchargez un .proto fichier, le système:
- Parse le proto basé sur regex-
ProtoParserpour JSON/HTTP - Compiles pour la réflexion utilisant protobuf-netM SK1Reflection's
FileDescriptorSet:var fileSet = new FileDescriptorSet { ImportPath = { "." } }; fileSet.Add(protoName, true, new StringReader(protoContent)); fileSet.Process(); // Compiles the .proto file - Convertir les descripteurs entre les formats protobuf-net et Google.Protobuf pour la compatibilité
- Entreposer les deux représentations pour le soutien du protocole dual-
Méthodes de travail actuelles:
# Provide proto file manually to grpcurl (always works)
grpcurl -proto yourfile.proto localhost:5116 list
# Use the JSON endpoint for testing (no grpcurl needed)
curl http://localhost:5116/api/grpc/UserService/GetUser \
-H "Content-Type: application/json" \
-d '{"user_id": 123}'
# Check available services via management API
curl http://localhost:5116/api/grpc-protos
# Use the interactive demo page at http://localhost:5116/Grpc
Pourquoi ne pas remplir complètement:
Le protocole de réflexion gRPC requiert:
- La cartographie du
ServerReflectionService RPC pour traiter les demandes de réflexion - Mise en œuvre correcte de toutes les méthodes de réflexion (ListServices , FileByFilename, etcM SK3
- Intégration avec l'infrastructure de serveur ASP.NET Core gRPC
Le fondement est en place - les fichiers proto sont compilés et des descripteurs disponibles. Les travaux restants consistent à cartographier le point final du service de réflexion et à assurer la compatibilité avec des outils comme grpcurl pour la découverte du serviceM SK2
Stratégies d'essai
Essais de navigateur avec JSON
Pour une itération rapide au cours du développement:
// Fetch API in browser
async function getUser(userId) {
const response = await fetch(`http://localhost:5116/api/grpc/UserService/GetUser`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_id: userId })
});
return await response.json();
}
const user = await getUser(12345);
console.log(user);
Évaluation de l'intégration avec Binaire
Pour des essais plus réalistes qui correspondent à la production:
#!/bin/bash
# Generate binary request
echo '{"user_id": 12345}' | \
protoc --encode=userservice.GetUserRequest user_service.proto > request.bin
# Call binary endpoint
curl -X POST http://localhost:5116/api/grpc/proto/UserService/GetUser \
-H "Content-Type: application/grpc+proto" \
--data-binary "@request.bin" \
--output response.bin
# Decode and verify
protoc --decode=userservice.User user_service.proto < response.bin
# Clean up
rm request.bin response.bin
Essais automatisés
Exemple xUnit test:
[Fact]
public async Task GrpcService_GetUser_ReturnsValidUser()
{
// Arrange
var protoContent = File.ReadAllText("user_service.proto");
await _client.PostAsync("/api/grpc-protos",
new StringContent(protoContent, Encoding.UTF8, "text/plain"));
var request = new { user_id = 12345 };
// Act
var response = await _client.PostAsJsonAsync(
"/api/grpc/UserService/GetUser", request);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var user = await response.Content.ReadFromJsonAsync<JsonElement>();
Assert.True(user.TryGetProperty("id", out _));
Assert.True(user.TryGetProperty("name", out _));
Assert.True(user.TryGetProperty("email", out _));
}
Troubleshooting
Défaut d'accélérer le prototype
Symptôme: Erreur lors du téléchargement d'un fichier .proto
{
"error": "No proto content provided"
}
Solution: Assurez-vous que vous envoyez correctement le contenu de la protofile.
- En tant que texte simple:
Content-Type: text/plain - En tant que forme à plusieurs parties:
Content-Type: multipart/form-data
Méthode non trouvée
Symptôme:
{
"error": "Method UserService/GetUser not found. Upload proto file first."
}
Solution:
- Vérifiez que le proto a été téléchargé:
GET /api/grpc-protos - Vérifier si les noms de service et de méthode correspondent exactement (caseM SK1sensitive)
- Assurez-vous que le type de méthode n’est pas unique (non en cours d’écoulementM SK1
JSON invalid en réponse
Symptôme: LLM retourne un JSON malformé
Cela peut se produire occasionnellement avec des structures ensemencées complexes. Le serveur modèle essaie d’extraire JSON de la réponse LLM, mais parfois le LLM inclut un texte ou une formattation supplémentaires .
Solution:
- Essayer de nouveau la demande (LLM les réponses varient)
- Simplifier la structure du message
- Vérifier si le LLM est correctement configuré dans les paramètres d'application
Les erreurs de Protobuf binaire
Symptôme: Le point final binaire retourne des erreurs ou des données malformées
Solution:
- Vérifiez que vous ' encodez correctement la demande avec
protoc - Vérifiez si le titre de contenu-Type est
application/grpc+proto - Assurer que le fichier proto corresponde à la structure du message
Considérations relatives au rendement
Parsage proto
Les fichiers proto sont analysés une fois le téléchargement et conservés dans la mémoire.
// Singleton storage
private readonly ConcurrentDictionary<string, ProtoDefinition> _definitions = new();
Dépenses liées à l'appel de LLM
Chaque appel de la méthode gRPC déclenche une demande LLM. Pour les essais de volume élevésM SK1
- Examiner les réponses de cache pour des demandes identiques
- Utiliser la fonction contextuelle pour maintenir l'uniformité
- Adjuster les paramètres de temps d'arrêt LLM si nécessaire
Serialisation binaire
La serialisation du protobuf binaire ajoute un minimum de frais généraux par rapport à JSON. Le commerceM SK1off:
- JSON: Serialisation plus rapide, débugging plus facile
- Binaire: Plus réaliste, charges de paye plus petitesM SK2 protocole de câble réel
Améliorations à venir
Caractéristiques prévues
- Enregistrement des serveurs - Soutien pour
returns (stream Response)Méthodes - Enregistrement des clients - Soutien pour
(stream Request) returnsMéthodes - Écoulement bidirectionnel - Traitement duplex complet
- Réfléction gRPC - Protocole de réflexion standard pour la compatibilité des outils
- Demande de validation - Parser et valider les demandes de Protobuf binaires en provenance
- Soutien Proto amélioré Importations
- Cache des réponses - Cache facultative pour les réponses déterministes
Contribuer
Aperçu d'un bug ou désir de contribuer? Vérifiez le répertoire GitHub pour obtenir les lignes directrices sur la contribution.
Résumé
La fonctionnalité de l'API mock gRPC offre une façon puissante d'essayer les services gR PC sans les mettre en œuvre. Avantages clés:
- Déposer les fichiers .proto et obtenir immédiatement des services de démonstration fonctionnels
- Choisissez entre JSON (convenienceM SK1 ou Protobuf binaire (realism)
- Les réponses générées par LLM- correspondent à vos schémas de message
- API de gestion complète pour les définitions proto
- Intégrer sans fil les fonctionnalités de l'API LLMock existante
Que vous soyez à l’essai basé sur - ou à la mise en place de suites d’essais d’intégration complètes, le double support JSON et binaire vous donnent la souplesse nécessaire pour travailler selon vos besoins.