As part of our Launch Week, we proudly release Platformatic v0.19!
At Platformatic, we are committed to making backend development frictionless. We aim to simplify all the time-consuming, low-value tasks that you do as day-to-day when developing backends. Last September, we released Platformatic DB to reduce the time to market for database-driven applications, and now we are going to remove another friction: writing clients for your other microservices.
Introducing platformatic client
Most companies in the world have followed the famous API mandate from Jeff Bezos:
- All teams will henceforth expose their data and functionality through service interfaces.
- Teams must communicate with each other through these interfaces.
- There will be no other form of interprocess communication allowed: no direct linking, no direct reads of another team’s data store, no shared-memory model, no back-doors whatsoever. The only communication allowed is via service interface calls over the network.
- It doesn’t matter what technology they use. HTTP, Corba, Pubsub, custom protocols — doesn’t matter.
- All service interfaces, without exception, must be designed from the ground up to be externalizable. That is to say, the team must plan and design to expose the interface to developers in the outside world. No exceptions.
- Anyone who doesn’t do this will be fired.
- Thank you; have a nice day!
Our Platformatic Cloud is built as a series of services that are orchestrated to deploy your applications in a matter of seconds. Quite a few of those components must be independent to ensure maximum resilience and ease of development (so multiple team members could not step into each other toes!). We noticed that we spent quite a bit of time writing API clients for each of those services: we knew we had to build a client, and we did in #794.
Platformatic Client generator
We are announcing a new command: platformatic client
. This command takes an OpenAPI Schema (in JSON format for now) or a GraphQL endpoint and automatically generates a client.
To create a client for another service, e.g. a movies
store, run the following in the root folder of your Platformatic project:
platformatic client https://target_service:target_port/documentation/json --name movies
This will create a few things for us inside a movies
folder:
movies.openapi.json
- the OpenAPI definition in JSON formatmovies.cjs
- a Fastify plugin to automatically load the clientmovies.d.ts
- the type definitions for that clientpackage.json
- the plugin metadata to set the plugin entry point
platformatic client
will also modify your platformatic.db.json
or platformatic.service.json
to add the following:
{
"clients": [{
"path": "./movies",
"url": "{PLT_MOVIES_URL}"
}]
}
Then you must add PLT_MOVIES_URL
as part of your .env
file. There is nothing else needed to start calling the movies
service.
Using Platformatic Client
Using the client is extremely simple. All the APIs are typed, so check out the generated types.
// Use a typescript reference to set up autocompletion
// and explore the generated APIs.
/// <reference path="./movies" />
/** @type {import('fastify').FastifyPluginAsync<{} */
module.exports = async function (app, opts) {
app.post('/', async (request, reply) => {
const res = await app.movies.graphql({
query: 'query { movies { title } }'
})
return res
})
}
or in Typescript, calling an OpenAPI endpoint:
import { FastifyInstance } from 'fastify'
/// <reference path="./movies" />
export default async function (app: FastifyInstance) {
app.get('/', async () => {
return app.movies.get({})
})
}
Programmatic usage of @platformatic/client
There is no need to use the generator if you don't need to! You can just use @platformatic/client
as a normal module (both cjs and esm), like so with OpenAPI:
import { buildOpenAPIClient } from '@platformatic/client'
const client = await buildOpenAPIClient({
url: `https://yourapi.com/documentation/json`
// file: 'path/to/openapi.json'
})
const res = await client.yourOperationName({ foo: 'bar' })
console.log(res)
or for GraphQL:
import { buildGraphQLClient } from '@platformatic/client'
const client = await buildGraphQLClient({
url: `https://yourapi.com/graphql`,
// path: 'path/to/schema.graphql'
})
const res = await client.graphql({
query: `
mutation createMovie($title: String!) {
saveMovie(input: {title: $title}) {
id
title
}
}
`,
variables: {
title: 'The Matrix'
}
})
console.log(res)
Platformatic v0.19.0
Platformatic v0.19.0 ships with some other key features: type definitions and HTTPS configurations.
Platformatic Service Type Definitions
Platformatic Service now has type definitions, as implemented by y @rozzilla in #806:
Other fixes
- Update configuration doc by @rozzilla in #789
- feat(issue#793): Standalone PLT service module by @rozzilla in #797
- docs(contributing): Add troubleshooting section by @rozzilla in #800
- Implement custom schema keyword to resolve a local path by @mcollina in #798
- Ask the user to overwrite the readme in create-platformatic by @mcollina in #804
- Prevent cyclic deps by @mcollina in #802
- service: add support for HTTPS keys and certs by @cjihrig in #791