It's Platformatic Client time in the v0.19.0 release!

It's Platformatic Client time in the v0.19.0 release!

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:

  1. All teams will henceforth expose their data and functionality through service interfaces.
  2. Teams must communicate with each other through these interfaces.
  3. 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.
  4. It doesn’t matter what technology they use. HTTP, Corba, Pubsub, custom protocols — doesn’t matter.
  5. 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.
  6. Anyone who doesn’t do this will be fired.
  7. 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 format
  • movies.cjs - a Fastify plugin to automatically load the client
  • movies.d.ts - the type definitions for that client
  • package.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:

image

Other fixes