Skip to content

Commit 77c0df3

Browse files
committed
test: add an example of custom mutation resolver with tag adding to existed record via script
Related #37
1 parent 24ac087 commit 77c0df3

File tree

6 files changed

+176
-10
lines changed

6 files changed

+176
-10
lines changed

README.md

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ graphql-compose-elasticsearch
33

44
[![](https://img.shields.io/npm/v/graphql-compose-elasticsearch.svg)](https://www.npmjs.com/package/graphql-compose-elasticsearch)
55
[![npm](https://img.shields.io/npm/dt/graphql-compose-elasticsearch.svg)](http://www.npmtrends.com/graphql-compose-elasticsearch)
6-
[![Travis](https://img.shields.io/travis/nodkz/graphql-compose-elasticsearch.svg?maxAge=2592000)](https://travis-ci.org/nodkz/graphql-compose-elasticsearch)
6+
[![Travis](https://img.shields.io/travis/graphql-compose/graphql-compose-elasticsearch.svg?maxAge=2592000)](https://travis-ci.org/graphql-compose/graphql-compose-elasticsearch)
77
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
88
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
9-
[![Greenkeeper badge](https://badges.greenkeeper.io/nodkz/graphql-compose-elasticsearch.svg)](https://greenkeeper.io/)
109

1110
This module expose Elastic Search REST API via GraphQL.
1211

@@ -46,7 +45,7 @@ const schema = new GraphQLSchema({
4645
});
4746
```
4847

49-
Full [code example](https://github.com/nodkz/graphql-compose-elasticsearch/tree/master/examples/differentVersions)
48+
Full [code example](https://github.com/graphql-compose/graphql-compose-elasticsearch/tree/master/examples/differentVersions)
5049

5150
Live demo of [Introspection of Elasticsearch API via Graphiql](https://graphql-compose.herokuapp.com/elasticsearch/)
5251

@@ -126,7 +125,7 @@ const Schema = new GraphQLSchema({
126125
});
127126
```
128127

129-
Full [code example](https://github.com/nodkz/graphql-compose-elasticsearch/blob/master/examples/elastic50/index.js)
128+
Full [code example](https://github.com/graphql-compose/graphql-compose-elasticsearch/blob/master/examples/elastic50/index.js)
130129

131130
## Installation
132131
```
@@ -150,6 +149,36 @@ Modules `graphql`, `graphql-compose`, `elasticsearch` are in `peerDependencies`,
150149
### Mapping: Generated GraphQL Types and Documentation
151150
<img width="1703" alt="screen shot 2017-03-22 at 19 33 24" src="https://cloud.githubusercontent.com/assets/1946920/24200220/a05944b6-0f36-11e7-9919-39b7001af203.png">
152151

152+
## FAQ
153+
154+
### Creating custom Resolvers
155+
156+
If you need create something special, you may create a custom Resolver. For example, if you need to add a new tag for existing record, do it in the following manner ([see full test-case](https://github.com/graphql-compose/graphql-compose-elasticsearch/blob/master/src/__tests__/github_issues/37-test.js)):
157+
158+
```js
159+
ActivitiesEsTC.addResolver({
160+
name: 'addTag',
161+
kind: 'mutation',
162+
type: 'JSON',
163+
args: {
164+
id: 'String!',
165+
tag: 'String!',
166+
},
167+
resolve: ({ args }) => {
168+
return elasticClient.update({
169+
index: elasticIndex,
170+
type: elasticType,
171+
id: args.id,
172+
body: {
173+
script: {
174+
inline: 'ctx._source.tags.add(params.tag)',
175+
params: { tag: args.tag },
176+
},
177+
},
178+
});
179+
},
180+
});
181+
```
153182

154183
## License
155-
[MIT](https://github.com/nodkz/graphql-compose-elasticsearch/blob/master/LICENSE.md)
184+
[MIT](https://github.com/graphql-compose/graphql-compose-elasticsearch/blob/master/LICENSE.md)

scripts/docker/es2/Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
from elasticsearch:2-alpine
1+
FROM elasticsearch:2-alpine
22

3-
copy elasticsearch.yml /usr/share/elasticsearch/config/elasticsearch.yml
3+
COPY elasticsearch.yml /usr/share/elasticsearch/config/elasticsearch.yml
4+
ENV ES_JAVA_OPTS="-Xms750m -Xmx750m"

scripts/docker/es5/Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
from elasticsearch:5-alpine
1+
FROM docker.elastic.co/elasticsearch/elasticsearch:5.2.1
22

3-
copy elasticsearch.yml /usr/share/elasticsearch/config/elasticsearch.yml
3+
COPY elasticsearch.yml /usr/share/elasticsearch/config/elasticsearch.yml
4+
ENV ES_JAVA_OPTS="-Xms750m -Xmx750m"

scripts/docker/es5/elasticsearch.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ network.host: 0.0.0.0
33
http.cors.enabled: true
44
http.cors.allow-origin: "*"
55
cluster.name: elasticsearch_nodkz
6+
xpack.security.enabled: false

src/__tests__/github_issues/32-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const ActivitiesEsTC = composeWithElastic({
3333
}),
3434
});
3535

36-
describe('github issue #72 - hits returns me the found id, score, type...', () => {
36+
describe('github issue #32 - hits returns me the found id, score, type...', () => {
3737
it('test `search` resolver', () => {
3838
expect(ActivitiesEsTC).toBeInstanceOf(TypeComposer);
3939

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/* @flow */
2+
3+
import elasticsearch from 'elasticsearch';
4+
import { TypeComposer, schemaComposer } from 'graphql-compose';
5+
import { graphql } from 'graphql';
6+
import { composeWithElastic } from '../..';
7+
8+
const ELASTICSEARCH_HOST = '';
9+
const ELASTICSEARCH_API_VERSION = '5.2';
10+
const mapping = {
11+
properties: {
12+
id: {
13+
type: 'keyword',
14+
},
15+
title: {
16+
type: 'text',
17+
},
18+
tags: {
19+
type: 'text',
20+
},
21+
},
22+
};
23+
24+
const elasticClient = new elasticsearch.Client({
25+
host: ELASTICSEARCH_HOST,
26+
apiVersion: ELASTICSEARCH_API_VERSION,
27+
log: 'info', // FOR DETAILED DEBUG USE - 'trace'
28+
});
29+
const elasticIndex = 'github37';
30+
const elasticType = 'activities';
31+
32+
const ActivitiesEsTC = composeWithElastic({
33+
graphqlTypeName: 'SearchActivities',
34+
elasticMapping: mapping,
35+
pluralFields: ['tags'],
36+
elasticIndex,
37+
elasticType,
38+
elasticClient,
39+
});
40+
41+
beforeAll(async () => {
42+
const indexExists = await elasticClient.indices.exists({ index: elasticIndex });
43+
if (indexExists) {
44+
await elasticClient.indices.delete({ index: elasticIndex });
45+
}
46+
47+
// create demo record directly in elastic
48+
await elasticClient.create({
49+
index: elasticIndex,
50+
type: elasticType,
51+
id: '333',
52+
body: {
53+
title: 'Test 1',
54+
tags: ['y', 'z'],
55+
},
56+
});
57+
});
58+
59+
describe('github issue #37 - Mutations via updateById overwrite arrays instead of appending to them', () => {
60+
it('create custom resolver', async () => {
61+
expect(ActivitiesEsTC).toBeInstanceOf(TypeComposer);
62+
63+
ActivitiesEsTC.addResolver({
64+
name: 'addTag',
65+
kind: 'mutation',
66+
type: 'JSON',
67+
args: {
68+
id: 'String!',
69+
tag: 'String!',
70+
},
71+
resolve: ({ args }) => {
72+
return elasticClient.update({
73+
index: elasticIndex,
74+
type: elasticType,
75+
id: args.id,
76+
body: {
77+
script: {
78+
inline: 'ctx._source.tags.add(params.tag)',
79+
params: { tag: args.tag },
80+
},
81+
},
82+
});
83+
},
84+
});
85+
86+
// create simple Schema for EE test
87+
schemaComposer.Query.addFields({ noop: 'String' }); // by spec query MUST be always present
88+
schemaComposer.Mutation.addFields({
89+
activitiesAddTag: ActivitiesEsTC.getResolver('addTag'),
90+
});
91+
const schema = schemaComposer.buildSchema();
92+
93+
// update record via graphql
94+
const graphqlResponse = await graphql({
95+
schema,
96+
source: `
97+
mutation {
98+
activitiesAddTag(id: "333", tag: "x")
99+
}
100+
`,
101+
});
102+
103+
// check graphql response
104+
expect(graphqlResponse).toEqual({
105+
data: {
106+
activitiesAddTag: {
107+
_id: '333',
108+
_index: 'github37',
109+
_shards: { failed: 0, successful: 1, total: 2 },
110+
_type: 'activities',
111+
_version: 2,
112+
result: 'updated',
113+
},
114+
},
115+
});
116+
117+
// check demo record directly in elastic
118+
const elasticData = await elasticClient.get({
119+
index: elasticIndex,
120+
type: elasticType,
121+
id: '333',
122+
_source: true,
123+
});
124+
125+
expect(elasticData).toEqual({
126+
_id: '333',
127+
_index: 'github37',
128+
_source: { tags: ['y', 'z', 'x'], title: 'Test 1' },
129+
_type: 'activities',
130+
_version: 2,
131+
found: true,
132+
});
133+
});
134+
});

0 commit comments

Comments
 (0)