update using API first development (#140)

diff --git a/basic/apis/consumer-api/pom.xml b/basic/apis/consumer-api/pom.xml
new file mode 100644
index 0000000..4faa106
--- /dev/null
+++ b/basic/apis/consumer-api/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.servicecomb.samples</groupId>
+    <artifactId>basic-apis</artifactId>
+    <version>3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>basic-consumer-api</artifactId>
+  <packaging>jar</packaging>
+
+</project>
\ No newline at end of file
diff --git a/basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java b/basic/apis/consumer-api/src/main/java/org/apache/servicecomb/samples/api/ConsumerService.java
similarity index 67%
copy from basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
copy to basic/apis/consumer-api/src/main/java/org/apache/servicecomb/samples/api/ConsumerService.java
index a404a56..e5e8830 100644
--- a/basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
+++ b/basic/apis/consumer-api/src/main/java/org/apache/servicecomb/samples/api/ConsumerService.java
@@ -15,10 +15,17 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.samples;
+package org.apache.servicecomb.samples.api;
 
-public interface ProviderService {
-  String sayHello(String name);
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 
+@RequestMapping(path = "/")
+public interface ConsumerService {
+  @GetMapping("/sayHello")
+  String sayHello(@RequestParam("name") String name);
+
+  @GetMapping("/exampleConfig")
   String exampleConfig();
 }
diff --git a/basic/apis/pom.xml b/basic/apis/pom.xml
new file mode 100644
index 0000000..97b05b4
--- /dev/null
+++ b/basic/apis/pom.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.servicecomb.samples</groupId>
+    <artifactId>basic-application</artifactId>
+    <version>3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>basic-apis</artifactId>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>provider-api</module>
+    <module>consumer-api</module>
+  </modules>
+
+</project>
\ No newline at end of file
diff --git a/basic/apis/provider-api/pom.xml b/basic/apis/provider-api/pom.xml
new file mode 100644
index 0000000..a643892
--- /dev/null
+++ b/basic/apis/provider-api/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.servicecomb.samples</groupId>
+    <artifactId>basic-apis</artifactId>
+    <version>3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>basic-provider-api</artifactId>
+  <packaging>jar</packaging>
+
+</project>
\ No newline at end of file
diff --git a/basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java b/basic/apis/provider-api/src/main/java/org/apache/servicecomb/samples/api/ProviderService.java
similarity index 69%
rename from basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
rename to basic/apis/provider-api/src/main/java/org/apache/servicecomb/samples/api/ProviderService.java
index a404a56..88155a5 100644
--- a/basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
+++ b/basic/apis/provider-api/src/main/java/org/apache/servicecomb/samples/api/ProviderService.java
@@ -15,10 +15,17 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.samples;
+package org.apache.servicecomb.samples.api;
 
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@RequestMapping(path = "/provider")
 public interface ProviderService {
-  String sayHello(String name);
+  @GetMapping("/sayHello")
+  String sayHello(@RequestParam("name") String name);
 
+  @GetMapping("/exampleConfig")
   String exampleConfig();
 }
diff --git a/basic/consumer/pom.xml b/basic/consumer/pom.xml
index 53f15b2..0ed7959 100644
--- a/basic/consumer/pom.xml
+++ b/basic/consumer/pom.xml
@@ -33,6 +33,16 @@
       <groupId>org.apache.servicecomb</groupId>
       <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb.samples</groupId>
+      <artifactId>basic-consumer-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb.samples</groupId>
+      <artifactId>basic-provider-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 
   <build>
diff --git a/basic/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java b/basic/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java
index 9dfa17a..84c5ce9 100644
--- a/basic/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java
+++ b/basic/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java
@@ -17,25 +17,26 @@
 
 package org.apache.servicecomb.samples;
 
-import org.apache.servicecomb.provider.pojo.RpcReference;
 import org.apache.servicecomb.provider.rest.common.RestSchema;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
+import org.apache.servicecomb.samples.api.ConsumerService;
+import org.apache.servicecomb.samples.api.ProviderService;
+import org.springframework.beans.factory.annotation.Autowired;
 
-@RestSchema(schemaId = "ConsumerController")
-@RequestMapping(path = "/")
-public class ConsumerController {
-  @RpcReference(schemaId = "ProviderController", microserviceName = "provider")
+@RestSchema(schemaId = "ConsumerController", schemaInterface = ConsumerService.class)
+public class ConsumerController implements ConsumerService {
   private ProviderService providerService;
 
-  // consumer service which delegate the implementation to provider service.
-  @GetMapping("/sayHello")
-  public String sayHello(@RequestParam("name") String name) {
+  @Autowired
+  public void setProviderService(ProviderService providerService) {
+    this.providerService = providerService;
+  }
+
+  @Override
+  public String sayHello(String name) {
     return providerService.sayHello(name);
   }
 
-  @GetMapping("/exampleConfig")
+  @Override
   public String exampleConfig() {
     return providerService.exampleConfig();
   }
diff --git a/basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java b/basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderServiceConfiguration.java
similarity index 66%
copy from basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
copy to basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderServiceConfiguration.java
index a404a56..851b8e9 100644
--- a/basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
+++ b/basic/consumer/src/main/java/org/apache/servicecomb/samples/ProviderServiceConfiguration.java
@@ -17,8 +17,15 @@
 
 package org.apache.servicecomb.samples;
 
-public interface ProviderService {
-  String sayHello(String name);
+import org.apache.servicecomb.provider.pojo.Invoker;
+import org.apache.servicecomb.samples.api.ProviderService;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
 
-  String exampleConfig();
+@Configuration
+public class ProviderServiceConfiguration {
+  @Bean
+  public ProviderService providerService() {
+    return Invoker.createProxy("provider", "ProviderController", ProviderService.class);
+  }
 }
diff --git a/basic/pom.xml b/basic/pom.xml
index bd69985..18290fb 100644
--- a/basic/pom.xml
+++ b/basic/pom.xml
@@ -27,7 +27,7 @@
 
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <servicecomb.version>3.0.0</servicecomb.version>
+    <servicecomb.version>3.1.0</servicecomb.version>
     <spring-boot-maven-plugin.version>3.1.3</spring-boot-maven-plugin.version>
     <maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
   </properties>
@@ -102,6 +102,7 @@
   </profiles>
 
   <modules>
+    <module>apis</module>
     <module>provider</module>
     <module>consumer</module>
     <module>gateway</module>
diff --git a/basic/provider/pom.xml b/basic/provider/pom.xml
index b02dfd0..3140127 100644
--- a/basic/provider/pom.xml
+++ b/basic/provider/pom.xml
@@ -37,6 +37,11 @@
       <groupId>org.apache.servicecomb</groupId>
       <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb.samples</groupId>
+      <artifactId>basic-provider-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 
   <build>
diff --git a/basic/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java b/basic/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java
index 2db6ccb..15d8f70 100644
--- a/basic/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java
+++ b/basic/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java
@@ -19,14 +19,11 @@
 
 import org.apache.servicecomb.config.DynamicProperties;
 import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.apache.servicecomb.samples.api.ProviderService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
 
-@RestSchema(schemaId = "ProviderController")
-@RequestMapping(path = "/")
-public class ProviderController {
+@RestSchema(schemaId = "ProviderController", schemaInterface = ProviderService.class)
+public class ProviderController implements ProviderService {
   private DynamicProperties dynamicProperties;
 
   private String example;
@@ -38,13 +35,12 @@
         value -> this.example = value, "not set");
   }
 
-  // a very simple service to echo the request parameter
-  @GetMapping("/sayHello")
-  public String sayHello(@RequestParam("name") String name) {
+  @Override
+  public String sayHello(String name) {
     return "Hello " + name;
   }
 
-  @GetMapping("/exampleConfig")
+  @Override
   public String exampleConfig() {
     return example;
   }