Papupata Documentation

Guide: setting up papupata for clients

Overview

When you want to use papupata to make API calls, you first need to set it up. This guide covers the most common cases and gives pointer for less common ones.

Table of contents

Prerequisites

Before starting this guide, you need to have an API declaration. For information on how to get there, see Declaring APIs.

The Basics

There are a few things that always need to be set up when you want to make requests with papupata:

  • Base URL, that is, where to connect to
  • A mechanism for actually making requests

As this time there are no other settings.

The configuration happens using the configure

method on an API declaration.
const API = new APIDeclaration()
API.configure({
  baseUrl: 'https://example.com',
})

If you want to only update some of the settings, you can get the existing configure and reconfigure the api declaration based on it.

const API = new APIDeclaration()
API.configure({
  ...api.getConfig(),
  baseUrl: 'https://example.com',
})

Alternatively, from version 2.0.0 onwards you can use the updateConfig function to do the same.

const API = new APIDeclaration()
API.updateConfig({
  baseUrl: 'https://example.com',
})

Base URL

The base URL is an URL where the declared APIs can be found. Typically it is either a blank string or combination of protocol and a hostname, but it is possible to include a path as well.

In browser world APIs are commonly hosted from the same server that also hosts the client. In these situations you generally want the URLs to be relative to the root of the current host. This can be accomplished by passing in an empty string as the base URL.

const api = API.declareGetAPI('/hello').response<string>()
API.configure({baseURL: ''})
await api() // invokes /hello

Sometimes the APIs are served by other servers, and if your client is a node.js application you are always going to have to provide an actual URL.

const api = API.declareGetAPI('/hello').response<string>()
API.configure({baseURL: 'https://www.example.com'})
await api() // invokes https://www.example.com/hello

At times it might be beneficial to implement the APIs somewhere other than the root of the server. Typically it'd be better to include the path in the actual API paths, but the clients can also include it in the base URL.

const api = API.declareGetAPI('/hello').response<string>()
API.configure({baseURL: 'https://www.example.com/api'})
await api() // invokes https://www.example.com/api/hello

Mechanism for making requests

Making HTTP requests in typescript can be tricky because of varying capabilities of execution environments. Different browsers and node.js have different options available, some of which might or might not suit all your needs.

Papupata makes no assumptions about the mechanism used to make the requests, instead one must be provided to it. This is done using the requestAdapter configuration option.

In many cases you might want to build your implementation, but there are two simple implementations provided with papupata, which can also serve as examples for your own implementations.

fetchAdapter

This utilizes global fetch, and as such is mostly suited for browsers. It only supports JSON bodies, responses can be either JSON or plain text. Any response codes above and including 400 cause a generic error to be thrown.

Simply put, in its current state the adapter is only really suitable for extremely simple use cases.

import fetchAdapter from 'papupata/adapters/fetch'
API.updateConfig({
  requestAdapter: fetchAdapter
})

Having said that, it should be fairly straightforward to expand the implementation to suit your needs.

requestPromiseAdapter

This adapter utilizes request-promise and while certainly simple it is much better suited for many purposes. It should be usable on both node.js and browser environments, supports json and form data as well as non-object bodies.

import createRequestPromiseAdapter from 'papupata/adapters/requestPromise'
API.updateConfig({
  requestAdapter: createRequestPromiseAdapter('json') // could pass 'form' for form data payloads
})

Regardless, it is quite likely that you'll want to create your own version to add some little things you need, such as headers.

Custom adapters

As has probably become evident, you'll likely want to create a custom adapter of your own. The easiest option is probably to take one of the existing adapters to use it as a template.

See custom request adapters for more information.

Conclusion

Now that papupata is set up to make requests, it should be a good time to make that happen!

See calling APIs for how to do exactly that.