|
| 1 | +An easy to use framework to build rest api service with [koa-neo4j](https://github.com/assister-ai/koa-neo4j-starter-kit),data models are fully declarative by [json-schema](http://json-schema.org/) |
| 2 | + |
| 3 | +## features |
| 4 | + |
| 5 | +* fully declarative koa routes,relationship in neo4j by json schema |
| 6 | + |
| 7 | +## data modeling based on json schema extension attributes |
| 8 | + |
| 9 | +### basic model |
| 10 | + |
| 11 | +``` |
| 12 | +{ |
| 13 | + "id": "User", |
| 14 | + "type": "object", |
| 15 | + "properties": { |
| 16 | + "alias": { |
| 17 | + "type": "string" |
| 18 | + }, |
| 19 | + "name": { |
| 20 | + "type": "string" |
| 21 | + }, |
| 22 | + "lang": { |
| 23 | + "type": "string" |
| 24 | + }, |
| 25 | + "userid":{ |
| 26 | + "type":"integer" |
| 27 | + }, |
| 28 | + "passwd":{ |
| 29 | + "type":"string" |
| 30 | + } |
| 31 | + }, |
| 32 | + "route":"/users" |
| 33 | +} |
| 34 | +``` |
| 35 | + |
| 36 | +* first each data model is a valid json schema,so model 'User' will be validated with [ajv](https://github.com/epoberezkin/ajv) as json object with fields and related data types as above |
| 37 | + |
| 38 | +* data model with attribute `"route":"/users"` will generate restful api interface with route `/users` |
| 39 | + |
| 40 | +``` |
| 41 | +POST /users |
| 42 | +
|
| 43 | +PUT /users/:uuid |
| 44 | +
|
| 45 | +DELETE /users/:uuid |
| 46 | +
|
| 47 | +GET /users/:uuid |
| 48 | +
|
| 49 | +GET /users |
| 50 | +``` |
| 51 | + |
| 52 | +* `"id":"User"` is not only the id of the json schema but also the label of the node stored in neo4j |
| 53 | + |
| 54 | +### model reference others |
| 55 | + |
| 56 | +``` |
| 57 | +{ |
| 58 | + "id": "ConfigurationItem", |
| 59 | + "type": "object", |
| 60 | + "properties": { |
| 61 | + "name": { |
| 62 | + "type": "string" |
| 63 | + }, |
| 64 | + "responsibility":{ |
| 65 | + "type": "integer", |
| 66 | + "schema":"User", |
| 67 | + "relationship":{"name":"RESPONSIBLE_FOR","reverse":true} |
| 68 | + }, |
| 69 | + ... |
| 70 | + }, |
| 71 | + "required": ["name"], |
| 72 | + "route": "/cfgItems", |
| 73 | + "search":{"index":"cmdb"} |
| 74 | +} |
| 75 | +``` |
| 76 | + |
| 77 | +* `schema` means field `responsibility` in model `ConfigurationItem` reference model `User` and will generate relationship in neo4j as following |
| 78 | + |
| 79 | + (:ConfigurationItem)<-[:RESPONSIBLE_FOR]-(:User) |
| 80 | + |
| 81 | +* `search` means instance of `ConfigurationItem` will also stored in elasticsearch with `cmdb` as index name |
| 82 | + |
| 83 | +## Search |
| 84 | + |
| 85 | +* query interfaces which use cypher and elasticsearch dsl(will I called eql) directly |
| 86 | + |
| 87 | +```cypher |
| 88 | +api/searchByCypher |
| 89 | +{ |
| 90 | + "category":"ITService", |
| 91 | + "search":["email","pop3"], |
| 92 | + "cypher":"OPTIONAL MATCH (s1:ITService) WHERE s1.uuid IN {search} or s1.group IN {search} WITH COLLECT(distinct(s1.uuid)) as services_byIds UNWIND {search} as keyword OPTIONAL MATCH (s1:ITService)-[:BelongsTo]->(sg:ITServiceGroup) WHERE s1.name = keyword or sg.name = keyword WITH services_byIds+collect(distinct(s1.uuid)) as services UNWIND services AS service RETURN COLLECT(distinct service)" |
| 93 | +} |
| 94 | +``` |
| 95 | + |
| 96 | +`category` is id of the model,`cypher` is the raw cypher query, other fields are required parameters in cypher query |
| 97 | + |
| 98 | +```eql |
| 99 | +api/searchByEql |
| 100 | +{ |
| 101 | + "category":"ConfigurationItem", |
| 102 | + "body": |
| 103 | + { |
| 104 | + "query": { |
| 105 | + "bool":{ |
| 106 | + "must":[ |
| 107 | + {"match": {"category": "Router"}}, |
| 108 | + {"match":{"status.status":"In_Use"}}, |
| 109 | + {"match":{"it_service":"{{service_email_id}}"}} |
| 110 | + ] |
| 111 | + } |
| 112 | +
|
| 113 | + }, |
| 114 | + "sort" : [ |
| 115 | + { "product_date" : {"order" : "desc"}}] |
| 116 | + } |
| 117 | +} |
| 118 | +``` |
| 119 | + |
| 120 | +`category` is id of the model,`body` is the raw eql |
| 121 | + |
| 122 | + |
| 123 | +## Deploy |
| 124 | + |
| 125 | +1. install db server |
| 126 | + |
| 127 | + [neo4j](http://neo4j.com/docs/operations-manual/current/installation/) |
| 128 | + |
| 129 | + [elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/master/_installation.html) |
| 130 | + |
| 131 | + [redis](https://redis.io/topics/quickstart) |
| 132 | + |
| 133 | +2. install npm dependencies |
| 134 | + |
| 135 | + npm install |
| 136 | + |
| 137 | +3. configuration |
| 138 | + |
| 139 | + modify value in config/default.json to match db configuration |
| 140 | + |
| 141 | + ``` |
| 142 | + "neo4j": { |
| 143 | + "host": "localhost", |
| 144 | + "port": 7687, |
| 145 | + "http_port":7474, |
| 146 | + "user": "neo4j", |
| 147 | + "password": "neo4j" |
| 148 | + }, |
| 149 | + "elasticsearch":{ |
| 150 | + "host": "localhost", |
| 151 | + "port": 9200, |
| 152 | + "requestTimeout":3000, |
| 153 | + "mode": "strict" |
| 154 | + }, |
| 155 | + "redis": { |
| 156 | + "host": "localhost", |
| 157 | + "port": 6379 |
| 158 | + }, |
| 159 | + ``` |
| 160 | +
|
| 161 | +
|
| 162 | +4. init Schema |
| 163 | +
|
| 164 | + npm run init |
| 165 | +
|
| 166 | +5. start |
| 167 | +
|
| 168 | + npm start |
| 169 | + |
| 170 | +
|
| 171 | +6. run integration test cases with [postman](https://www.getpostman.com/docs/) |
| 172 | +
|
| 173 | + npm test |
| 174 | +
|
0 commit comments