Posted on: April 21, 2025 Posted by: rahulgite Comments: 0

How can we implement a REST endpoint using a GET request to filter Employee entities based on any of their fields, without adding all 100+ fields as request parameters, and further support field-level data sources dynamically without changing application code or application.yml?

Answer:

To achieve zero-code and zero-config dynamic filtering, we design a system where each field of an Employee can pull its data from different data sources or queries based on metadata stored in a database table instead of application.yml.


✅ Step 1: Create Metadata Table

CREATE TABLE employee_field_sources (
  field_name VARCHAR(100) PRIMARY KEY,
  query TEXT NOT NULL,
  datasource_bean VARCHAR(100) NOT NULL
);

Sample Data:

INSERT INTO employee_field_sources VALUES ('empId', 'SELECT emp_id FROM employee_main WHERE id = ?', 'empDsJdbc');
INSERT INTO employee_field_sources VALUES ('fname', 'SELECT fname FROM employee_names WHERE id = ?', 'nameDsJdbc');
INSERT INTO employee_field_sources VALUES ('designation', 'SELECT designation FROM hr_data WHERE id = ?', 'hrDsJdbc');

✅ Step 2: Register Field Sources Dynamically

@Component
public class FieldSourceRegistry {

    @Autowired
    private JdbcTemplate defaultJdbcTemplate; // From the metadata DB

    private final Map<String, FieldSource> fieldSources = new HashMap<>();

    @PostConstruct
    public void loadFieldSources() {
        List<Map<String, Object>> rows = defaultJdbcTemplate.queryForList("SELECT * FROM employee_field_sources");
        for (Map<String, Object> row : rows) {
            FieldSource fs = new FieldSource();
            fs.setQuery((String) row.get("query"));
            fs.setDatasourceBean((String) row.get("datasource_bean"));
            fieldSources.put((String) row.get("field_name"), fs);
        }
    }

    public FieldSource get(String fieldName) {
        return fieldSources.get(fieldName);
    }

    public static class FieldSource {
        private String query;
        private String datasourceBean;
        // Getters and setters
    }
}

✅ Step 3: Dynamic Fetcher

@Component
public class DynamicFieldFetcher {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private FieldSourceRegistry registry;

    public Object fetch(String field, Long empId) {
        FieldSourceRegistry.FieldSource meta = registry.get(field);
        if (meta == null) return null;

        JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean(meta.getDatasourceBean());

        return jdbcTemplate.queryForObject(meta.getQuery(), new Object[]{empId}, Object.class);
    }
}

✅ Step 4: Define Multiple JdbcTemplates (for different DBs)

@Configuration
public class DataSourceConfig {

    @Bean(name = "empDsJdbc")
    public JdbcTemplate empJdbcTemplate(@Qualifier("empDataSource") DataSource ds) {
        return new JdbcTemplate(ds);
    }

    @Bean(name = "nameDsJdbc")
    public JdbcTemplate nameJdbcTemplate(@Qualifier("nameDataSource") DataSource ds) {
        return new JdbcTemplate(ds);
    }

    @Bean(name = "hrDsJdbc")
    public JdbcTemplate hrJdbcTemplate(@Qualifier("hrDataSource") DataSource ds) {
        return new JdbcTemplate(ds);
    }
}

✅ Step 5: REST Controller

@RestController
@RequestMapping("/employees")
public class EmployeeController {

    @Autowired
    private DynamicFieldFetcher fieldFetcher;

    @GetMapping("/field")
    public ResponseEntity<Object> getField(@RequestParam String field, @RequestParam Long id) {
        Object value = fieldFetcher.fetch(field, id);
        return ResponseEntity.ok(value);
    }
}

✅ Sample GET Request

GET /employees/field?field=designation&id=101

If the employee_field_sources table has an entry for designation, it will:

  • Pick the right query
  • Pick the right datasource bean
  • Execute with id=101

✅ Benefits:

  • 💡 Fully dynamic
  • 📦 No code or YAML changes
  • ⚙️ New fields supported via DB insert only
  • 🧩 Easily extendable to non-SQL sources via strategy pattern

This is a highly scalable design for enterprise systems where field sources evolve and grow independently.

Leave a Comment