APIConfig extends Config { public <T> void service(Class<T> serviceInterface, T service) { logger.info("create web service, interface={}", serviceInterface.getCanonicalName()); var validator = new WebServiceInterfaceValidator(serviceInterface, context.beanClassValidator); validator.requestBeanReader = context.httpServer.handler.requestBeanReader; validator.responseBeanWriter = context.httpServer.handler.responseBeanWriter; validator.validate(); new WebServiceImplValidator<>(serviceInterface, service).validate(); new InjectValidator(service).validate(); context.serviceRegistry.serviceInterfaces.add(serviceInterface); for (Method method : serviceInterface.getMethods()) { HTTPMethod httpMethod = HTTPMethods.httpMethod(method); String path = method.getDeclaredAnnotation(Path.class).value(); Controller controller = new WebServiceControllerBuilder<>(serviceInterface, service, method).build(); try { Class<?> serviceClass = service.getClass(); Method targetMethod = serviceClass.getMethod(method.getName(), method.getParameterTypes()); String controllerInfo = serviceClass.getCanonicalName() + "." + targetMethod.getName(); String action = "api:" + ASCII.toLowerCase(httpMethod.name()) + ":" + path; context.httpServer.handler.route.add(httpMethod, path, new ControllerHolder(controller, targetMethod, controllerInfo, action, false)); } catch (NoSuchMethodException e) { throw new Error("failed to find impl method", e); } } }  void service(Class<T> serviceInterface, T service); APIClientConfig client(Class<T> serviceInterface, String serviceURL); T createClient(Class<T> serviceInterface, String serviceURL); HTTPClientBuilder httpClient(); void publishAPI(List<String> cidrs);  }
@Test void service() { config.service(TestWebService.class, new TestWebServiceImpl()); assertThat(config.context.serviceRegistry.serviceInterfaces).contains(TestWebService.class); }