REST
Metatype also allows you to consume your API in the same way you would consume regular REST APIs. It is as easy as calling a function: g.rest(..)
.
Here is a basic overview of how it looks like:
typegraph("example", (g) => {
// ..
g.expose({
getUsers: ..,
}, pub);
g.rest(`
query users($name: String, $rows: Integer) {
getUsers(name: $name, option: { maxRows: $rows } ) {
name
}
}
`);
// ..
});
General rule
query_type endpoint_name($param1: T1, $param2: T2, ..) {
exposed(..) {
f1
f2 ..
}
}
There is no rule in what type of query you should do most of the time as everything is up to you, however the type of query you set will define how your endpoint should be used.
In other words, depending on what query_type
(query or mutation), $param1, $param2, ..
will be defined from the request parameters (GET) or the request body (POST).
- query: Perform a
GET
at{TYPEGATE_URL}/{TG_NAME} /rest/endpoint_name?param1=..¶m2=..
- mutation: Perform a
POST
at{TYPEGATE_URL}/{TG_NAME} /rest/endpoint_name
withContent-Type
set asapplication/json
{
"param1": ..,
"param2": ..,
..
}
In the example above, for a local instance, the endpoint might look like: http://localhost:7890/example/rest/users?name=Bob&rows=10
Dynamic queries
This enables/disables all non-static queries, i.e. queries whose output or side effects depend on certain parameters.
By default, dynamic
is always on.
typegraph({ name: "my-typegraph", dynamic: false }, (g) => {
// ..
});
Auto-generated docs
In any case, you can always check the auto-generated documentation of the available endpoints, parameters, output shapes.
You can browse it at {TYPEGATE_URL}/{TG_NAME}/rest
.
OpenAPI clients
In some cases, as your typegraph gets more complicated, you may want to automate the step of writing clients and focus on the actual logic of your application instead.
The OpenAPI spec will be available at {TYPEGATE_URL}/{TG_NAME}/rest/__schema
, which is very useful considering that there are already a number of tools that enable you to create clients from an existing OpenAPI specification file.
Once you download the specification file for your API, it should look like something like this:
// {TYPEGATE_URL}/my_awesome_typegraph/rest/__schema
{
"openapi": "3.0.3",
"info": {
"title": "my_awesome_typegraph",
"license": {
"name": "MIT"
},
"description": "Rest endpoints for typegraph \"my_awesome_typegraph\"",
"version": "1.0.0"
},
"servers": [{ "url": "http://localhost:7890" }],
"paths": {
// typing each path manually on a custom client can be very tedious as your API grows
"/my_awesome_typegraph/rest/get_post": {
"get": {
"summary": "Perform get_post",
"operationId": "get_my_awesome_typegraph_get_post",
"responses": { ... }, // you will have various types per response status
"parameters": [ ... ]
}
},
"/my_awesome_typegraph/rest/get_post_id": { ... },
"/my_awesome_typegraph/rest/read_post": { ... }
},
"components": { ... }
}
Here are some of the most used generators:
- Multilang: OpenAPITools/openapi-generator
- Multilang: @openapitools/openapi-generator-cli
- Flutter: openapi_generator
To keep our setup simple, let us look at @openapitools/openapi-generator-cli, which is just a wrapper around openapi-generator and will download the appropriate dependencies for you.
First, install the cli globally
npm i -g @openapitools/openapi-generator-cli
In this example, let's generate a simple fetch client, you can refer to their official documentation for other generators.
openapi-generator-cli generate \
-i http://localhost:7890/my_awesome_typegraph/rest/__schema \
-g typescript-fetch \
-o my-client \
--skip-validate-spec
This will generate a fetch
-based typescript project.
.
+-- apis
¦ +-- DefaultApi.ts
¦ +-- index.ts
+-- models
¦ +-- Either10.ts
¦ +-- ErrorExtensions.ts
¦ ...
¦ +-- GetMyAwesomeTypegraphGetIdentity200Response.ts
¦ +-- Post.ts
¦ +-- User.ts
¦ +-- index.ts
+-- runtime.ts
+-- index.ts