refactor hello-koa demo
diff --git a/examples/hello-koa/package.json b/examples/hello-koa/package.json
index e3caa32..7082272 100644
--- a/examples/hello-koa/package.json
+++ b/examples/hello-koa/package.json
@@ -4,7 +4,8 @@
   "description": "A simple demo",
   "scripts": {
     "debug:start": "DEBUG=dubbo* ts-node ./src/server.ts",
-    "start": "ts-node ./src/server.ts"
+    "start": "ts-node ./src/server.ts",
+    "dubbo-server": "DEBUG=dubbo* ts-node ./src/dubbo/provider/dubbo.ts"
   },
   "keywords": [
     "apache-dubbo-js"
@@ -16,6 +17,7 @@
     "@types/koa-router": "^7.4.1"
   },
   "dependencies": {
+    "ip": "^1.1.5",
     "koa": "^2.4.1",
     "koa-router": "^7.3.0"
   }
diff --git a/examples/hello-koa/src/dubbo/dubbo.ts b/examples/hello-koa/src/dubbo/consumer/dubbo.ts
similarity index 100%
rename from examples/hello-koa/src/dubbo/dubbo.ts
rename to examples/hello-koa/src/dubbo/consumer/dubbo.ts
diff --git a/examples/hello-koa/src/dubbo/service.ts b/examples/hello-koa/src/dubbo/consumer/service.ts
similarity index 100%
rename from examples/hello-koa/src/dubbo/service.ts
rename to examples/hello-koa/src/dubbo/consumer/service.ts
diff --git a/examples/hello-koa/src/dubbo/provider/dubbo.ts b/examples/hello-koa/src/dubbo/provider/dubbo.ts
new file mode 100644
index 0000000..79905ac
--- /dev/null
+++ b/examples/hello-koa/src/dubbo/provider/dubbo.ts
@@ -0,0 +1,10 @@
+import {DubboServer} from 'apache-dubbo-js';
+import service from './service';
+
+const server = new DubboServer({
+  port: 20880,
+  registry: 'localhost:2181',
+  services: service,
+});
+
+server.start();
diff --git a/examples/hello-koa/src/dubbo/provider/service.ts b/examples/hello-koa/src/dubbo/provider/service.ts
new file mode 100644
index 0000000..b6dc18f
--- /dev/null
+++ b/examples/hello-koa/src/dubbo/provider/service.ts
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+import {IDubboService} from 'apache-dubbo-js';
+import ip from 'ip';
+
+interface IUserRequest {
+  id: number;
+  name: string;
+  email: string;
+  sex: number;
+}
+
+class UserResponse {
+  status: string;
+  info: Map<string, string>;
+}
+
+class TypeRequest {
+  map: Map<string, string>;
+  bigDecimal: {value: number};
+}
+
+//========================provider=======================
+
+class DemoProvider implements IDubboService {
+  clazz = 'org.apache.dubbo.demo.DemoProvider';
+  version = '1.0.0';
+  methods = {
+    sayHello(name: string) {
+      return `Hello ${name}, response from provider ${ip.address()}`;
+    },
+
+    echo() {
+      return 'pang';
+    },
+
+    test() {
+      console.log('test');
+    },
+
+    getUserInfo(request: IUserRequest) {
+      console.log(request);
+      const res = new UserResponse();
+      res.status = 'ok';
+      const map = new Map();
+      map.set('id', '1');
+      map.set('name', 'test');
+      res.info = map;
+      return res;
+    },
+  };
+}
+
+const basicTypeProvider = {
+  clazz: 'org.apache.dubbo.demo.BasicTypeProvider',
+  version: '1.0.0',
+  methods: {
+    testBasicType(req: TypeRequest) {
+      return req;
+    },
+  },
+};
+
+class ErrorProvider implements IDubboService {
+  clazz = 'org.apache.dubbo.demo.ErrorProvider';
+  version = '1.0.0';
+
+  methods = {
+    errorTest() {
+      throw new Error('ErrorProvider error');
+    },
+  };
+}
+
+export default [new DemoProvider(), basicTypeProvider, new ErrorProvider()];
diff --git a/examples/hello-koa/src/server.ts b/examples/hello-koa/src/server.ts
index 4fa050b..0bb766f 100644
--- a/examples/hello-koa/src/server.ts
+++ b/examples/hello-koa/src/server.ts
@@ -17,7 +17,7 @@
 
 import Koa from 'koa';
 import Router from 'koa-router';
-import dubbo from './dubbo/dubbo';
+import dubbo from './dubbo/consumer/dubbo';
 
 const app = new Koa();
 const router = new Router();
@@ -43,13 +43,13 @@
 
 router.get('/type', async ctx => {
   const {res, err} = await dubbo.service.basicTypeProvider.testBasicType();
-  ctx.body = res;
+  ctx.body = res || err.message;
 });
 
 router.get('/exp', async ctx => {
-  const {err, res} = await dubbo.service.errorProvider.errorTest();
-  console.log(err);
-  ctx.body = 'ok';
+  const {res, err} = await dubbo.service.errorProvider.errorTest();
+  console.log(res);
+  ctx.body = err.message;
 });
 
 router.get('/tracer', async ctx => {
diff --git a/examples/hello-koa/yarn.lock b/examples/hello-koa/yarn.lock
index 8fe11da..daab056 100644
--- a/examples/hello-koa/yarn.lock
+++ b/examples/hello-koa/yarn.lock
@@ -269,6 +269,11 @@
   resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
   integrity sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=
 
+ip@^1.1.5:
+  version "1.1.5"
+  resolved "http://npm.vivo.com.cn/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
+  integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
+
 is-generator-function@^1.0.7:
   version "1.0.7"
   resolved "https://registry.npm.taobao.org/is-generator-function/download/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522"
diff --git a/packages/dubbo/src/index.ts b/packages/dubbo/src/index.ts
index bba3812..3c9e3cd 100644
--- a/packages/dubbo/src/index.ts
+++ b/packages/dubbo/src/index.ts
@@ -22,7 +22,7 @@
 import {go} from './common/go';
 import {Registry, zk} from './registry';
 import setting from './setting';
-import {TDubboCallResult} from './types';
+import {IDubboService, TDubboCallResult} from './types';
 import DubboServer from './server/server';
 
 export {
@@ -40,4 +40,5 @@
   Registry,
   // types
   TDubboCallResult,
+  IDubboService,
 };