Skip to content

Commit

Permalink
GraphQL ADR: Prototype resolvers for tsp-client.ts
Browse files Browse the repository at this point in the history
Base this on below [1]'s instructions and resulting skeleton files,
amended for TSP's /health and (limited) /traces endpoints solely.

Include an executable bash ./test script with its assumptions documented
in it. Join an optional VS Code launch configuration that can replace
running [2] (below) manually; use it for occasional debugging too.

Using these hereby added resolvers depends on a running default
trace-server locally. Per [1], resolvers are in JavaScript as they only
demonstrate this limited scope. TypeScript may be used if ever expanding
such use of resolvers, depending on if GraphQL ever gets in TSP or not.

Refer to [3] from this repository, for how to call client's checkHealth;
refer to [4] for fetchTraces but only return their amount. More on how
to implement resolvers, including more advanced ones, is in [5]. REST
endpoints can otherwise be resolved through a data source [6], but that
approach remains out of this small prototype scope for now.

Document the nature of this prototype, along with steps, in the ADR. Add
the related reference about resolving Graph queries with REST endpoints.

[1] https://www.apollographql.com/docs/apollo-server/getting-started/
[2] node index.js
[3] trace-viewer-contribution.ts
[4] trace-manager.ts
[5] https://www.apollographql.com/docs/apollo-server/data/resolvers/
[6] https://www.apollographql.com/docs/apollo-server/data/data-sources/#restdatasource-reference

Signed-off-by: Marco Miller <marco.miller@ericsson.com>
  • Loading branch information
marco-miller committed Feb 12, 2022
1 parent b148568 commit f48afa8
Show file tree
Hide file tree
Showing 7 changed files with 970 additions and 2 deletions.
14 changes: 13 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,19 @@
"program": "test",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
"disableOptimisticBPs": true
},
{
"type": "node",
"request": "launch",
"name": "Apollo Server (GraphQL ADR)",
"cwd": "${workspaceFolder}/doc/adr/0002/graphql-server-prototype",
"args": [
"index.js"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true
}
]
}
20 changes: 19 additions & 1 deletion doc/adr/0002-GraphQL.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ graph TD
</details>

1. GraphQL would be offered as a TSP option alongside current REST endpoints.
1. Resolver functions in GraphQL Server would rely on current REST endpoints.
1. Resolver functions in GraphQL Server would [rely on current REST endpoints][rest].
1. Clients may then gradually benefit from the emerging GraphQL, through TSP.
1. GraphQL Server may then hide more and more endpoints less used by clients.

Expand Down Expand Up @@ -257,6 +257,23 @@ graph TD
* It is [based on React][svr-client], but [other integrations are listed][svr-client-open].
* This ADR doesn't require a deeper analysis yet, given TSP's current clients to integrate first.

#### Apollo Server prototype (TSP)

* Initialized based on the aforementioned trial [steps][svr-start].
* Showing a few small JavaScript resolvers in `index.js` for TSP `/health` and `/traces` endpoints.
* Which then relies on [tsp-typescript-client][client-ts] already part of this repository.
* Allowing this currently small prototype to potentially expand with more resolvers or trials.
* The steps below that exercise this prototype depend on a locally running, default `trace-server`.

```bash
cd ./0002/graphql-server-prototype
node index.js
./test
````

* Above, the `test` script is to be run from another terminal, after having launched the server.
* There is a VS Code launch configuration in this repository that can also run `node index.js`.

#### Testability

[Testing a GraphQL Server using Jest][jest]?
Expand Down Expand Up @@ -345,6 +362,7 @@ Each number referring to an aforementioned (previously numbered) risk.
[proto]: https://github.com/chentsulin/awesome-graphql#tools---prototyping
[py]: https://graphql.org/code/#python
[relay]: https://www.apollographql.com/blog/graphql/pagination/understanding-pagination-rest-graphql-and-relay/
[rest]: https://graphql.org/faq/#does-graphql-replace-rest
[rh]: https://www.redhat.com/en/topics/api/what-is-graphql#pros-and-cons
[svr-client]: https://www.apollographql.com/docs/react/
[svr-client-caching]: https://www.apollographql.com/docs/react/caching/overview/
Expand Down
3 changes: 3 additions & 0 deletions doc/adr/0002/graphql-server-prototype/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# About these files

Refer to `../../0002-GraphQL.md` to know more about these files and their purpose.
59 changes: 59 additions & 0 deletions doc/adr/0002/graphql-server-prototype/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// This is a stripped version of [1], down to showing TSP's /health and /traces endpoints.
// [1] https://www.apollographql.com/docs/apollo-server/getting-started/#step-3-define-your-graphql-schema

const { ApolloServer, gql } = require('apollo-server');
const { TspClient } = require('tsp-typescript-client/lib/protocol/tsp-client');

// A schema is a collection of type definitions (hence "typeDefs").
const typeDefs = gql`
# The "Query" type is special: it lists all of the available queries that
# clients can execute, along with the return type for each. Both non-nullable.
type Query {
status: String!
traces: Int!
}
`;

const baseUrl = "http://localhost:8080/tsp/api";

// Resolvers define the technique for fetching the types defined in the schema.
// Here, a default yet running trace-server is assumed for showcase simplicity.
const resolvers = {
Query: {
async status() {
const tspClient = new TspClient(baseUrl);
try {
const response = await tspClient.checkHealth();
if (response.isOk()) {
// Then assume presence of the corresponding model.
return response.getModel().status;
}
// Reliably return the resulting message otherwise.
return response.getStatusMessage();
} catch (error) {
// Likely caused by the missing local trace-server.
return error.message;
}
},
async traces() {
// Same simple approach as above. Returns how many traces only.
const tspClient = new TspClient(baseUrl);
try {
const response = await tspClient.fetchTraces();
if (response.isOk()) {
return response.getModel().length;
}
return response.getStatusCode();
} catch (error) {
return -1;
}
}
},
};

const server = new ApolloServer({ typeDefs, resolvers });

// The `listen` method launches a web server.
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Loading

0 comments on commit f48afa8

Please sign in to comment.