Skip to Content
Best Practices

Best Practices

Security

  1. Always use validation in production:

    LoadOptionsValidator validator = LoadOptionsValidator.builder() .maxTake(1_000) .maxSkip(10_000) .build(); GridDataProvider gridDataProvider = new GridDataProvider(dataSource, validator);
  2. Set appropriate query timeouts:

    gridDataProvider.setQueryTimeout(30); // 30 seconds for OLTP
  3. Never disable validation for public APIs

  4. Use DataSource mode for connection pooling

  5. Validate developer-defined SQL expressions in CI/CD

Performance

  1. Create indexes on filtered/sorted columns:

    CREATE INDEX idx_employees_lastname ON employees(last_name); CREATE INDEX idx_employees_salary ON employees(salary DESC); CREATE INDEX idx_employees_dept_salary ON employees(department_id, salary DESC);
  2. Use pagination for large result sets:

    {"take": 100, "skip": 0, "requireTotalCount": true}
  3. Limit nested entity depth to avoid N+1 queries

  4. Cache GridDataProvider instances (thread-safe in DataSource mode):

    @Bean public GridDataProvider gridDataProvider(DataSource dataSource) { return new GridDataProvider(dataSource); }

Thread Safety

  • Thread-safe for read operations (executeQuery, getData)
  • NOT thread-safe for setters (setQueryTimeout) - configure before sharing

Connection Mode

  • NOT thread-safe
  • Each thread should have its own GridDataProvider with its own Connection

Error Handling

try { DevExtremeResult<Employee> result = gridDataProvider .query(Employee.class) .loadOptions(loadOptions) .executeDevExtreme(); return result; } catch (IllegalArgumentException e) { // Invalid LoadOptions (validation failed) log.error("Invalid request: {}", e.getMessage()); return ResponseEntity.badRequest().body(e.getMessage()); } catch (ConnectionValidationException e) { // Database connection error log.error("Database connection failed", e); return ResponseEntity.status(503).body("Database unavailable"); } catch (QueryExecutionException e) { // Query execution error log.error("Query execution failed", e); return ResponseEntity.status(500).body("Query failed"); } catch (FilterConversionException e) { // Filter parsing error log.error("Invalid filter: {}", e.getMessage()); return ResponseEntity.badRequest().body("Invalid filter"); }
Last updated on