# ipfs-grpc-server

> A server library for the IPFS gRPC API

Latest version **0.12.1** (published 2023-05-25) · Apache-2.0 OR MIT license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install ipfs-grpc-server
pnpm add ipfs-grpc-server
yarn add ipfs-grpc-server
bun add ipfs-grpc-server
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 0.12.1 |
| Published | 2023-05-25 |
| First published | 2020-11-02 |
| Weekly downloads | 0 |
| License | Apache-2.0 OR MIT |
| TypeScript types | bundled |
| Module format | ESM |
| Node | >=16.0.0 |
| Dependencies | 17 |
| Unpacked size | 44.5 KB |
| Known vulnerabilities | 0 (+4 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 7390 |
| Maintainers | achingbrain, ipfs-npm-publisher-bot, npm-service-account-ipfs |
| Keywords | ipfs |

## Links

- npm: https://www.npmjs.com/package/ipfs-grpc-server
- Repository: https://github.com/ipfs/js-ipfs
- Homepage: https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-grpc-server#readme
- Issues: https://github.com/ipfs/js-ipfs/issues
- npm.io page: https://npm.io/package/ipfs-grpc-server

## Dependencies (17)

- [ws](https://npm.io/package/ws.md) ^8.5.0
- [it-map](https://npm.io/package/it-map.md) ^2.0.0
- [nanoid](https://npm.io/package/nanoid.md) ^4.0.0
- [coercer](https://npm.io/package/coercer.md) ^1.1.2
- [it-pipe](https://npm.io/package/it-pipe.md) ^2.0.3
- [it-first](https://npm.io/package/it-first.md) ^2.0.0
- [protobufjs](https://npm.io/package/protobufjs.md) ^7.0.0
- [change-case](https://npm.io/package/change-case.md) ^4.1.1
- [it-peekable](https://npm.io/package/it-peekable.md) ^2.0.0
- [it-pushable](https://npm.io/package/it-pushable.md) ^3.0.0
- [uint8arrays](https://npm.io/package/uint8arrays.md) ^4.0.2
- [@grpc/grpc-js](https://npm.io/package/@grpc/grpc-js.md) ^1.1.8
- [@libp2p/logger](https://npm.io/package/@libp2p/logger.md) ^2.0.5
- [@libp2p/peer-id](https://npm.io/package/@libp2p/peer-id.md) ^2.0.0
- [ipfs-core-types](https://npm.io/package/ipfs-core-types.md) ^0.14.1
- [ipfs-grpc-protocol](https://npm.io/package/ipfs-grpc-protocol.md) ^0.8.1
- [@multiformats/multiaddr](https://npm.io/package/@multiformats/multiaddr.md) ^11.1.5

## Recent versions

- 0.12.1 (latest) — 2023-05-25
- 0.12.0-7b79c1b8 (next) — 2023-05-25
- 0.12.0-6d95ce08 — 2023-05-25
- 0.12.0-4694e806 — 2023-05-25
- 0.12.0-e64813f6 — 2023-05-24
- 0.12.0-b64d4af0 — 2023-02-01
- 0.12.0-3bcabe38 — 2023-01-17
- 0.12.0-ab02e8f8 — 2023-01-17
- 0.12.0-6eeb1be5 — 2023-01-13
- 0.12.0 — 2023-01-12
- 0.11.0-d1c3abb3 — 2023-01-11
- 0.11.0-fa578bac — 2023-01-11
- 0.11.0-789ee585 — 2023-01-11
- 0.11.0-4b4c124c — 2023-01-11
- 0.11.0-5f73ecad — 2023-01-10
- … 221 more at https://npm.io/package/ipfs-grpc-server/versions

## README

> # ⛔️ DEPRECATED: [js-IPFS](https://github.com/ipfs/js-ipfs) has been superseded by [Helia](https://github.com/ipfs/helia)
>
> 📚 [Learn more about this deprecation](https://github.com/ipfs/js-ipfs/issues/4336) or [how to migrate](https://github.com/ipfs/helia/wiki/Migrating-from-js-IPFS)
>
> ⚠️ If you continue using this repo, please note that security fixes will not be provided

# ipfs-grpc-server <!-- omit in toc -->

[![ipfs.tech](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](https://ipfs.tech)
[![Discuss](https://img.shields.io/discourse/https/discuss.ipfs.tech/posts.svg?style=flat-square)](https://discuss.ipfs.tech)
[![codecov](https://img.shields.io/codecov/c/github/ipfs/js-ipfs.svg?style=flat-square)](https://codecov.io/gh/ipfs/js-ipfs)
[![CI](https://img.shields.io/github/actions/workflow/status/ipfs/js-ipfs/test.yml?branch=master\&style=flat-square)](https://github.com/ipfs/js-ipfs/actions/workflows/test.yml?query=branch%3Amaster)

> A server library for the IPFS gRPC API

## Table of contents <!-- omit in toc -->

- [Install](#install)
- [Why?](#why)
- [Protocol](#protocol)
  - [1. Metadata](#1-metadata)
  - [2. Messages](#2-messages)
    - [Signal](#signal)
    - [Header](#header)
    - [Message data](#message-data)
    - [Trailer](#trailer)
- [Handlers](#handlers)
  - [Metadata](#metadata)
  - [Unary](#unary)
  - [Server streaming](#server-streaming)
  - [Client streaming](#client-streaming)
  - [Bidirectional streaming](#bidirectional-streaming)
- [License](#license)
- [Contribute](#contribute)

## Install

```console
$ npm i ipfs-grpc-server
```

## Why?

[gRPC-web](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md) allows us to form HTTP requests out of gRPC invocations, but the [official implementation](https://github.com/grpc/grpc-web) supports only unary calls and server streaming, which in terms of functionality doesn't give us much over the existing [ipfs-http-client](https://www.npmjs.com/package/ipfs-http-client).

In order to support streaming file uploads with errors, pubsub, etc, bi-directional streaming is required.  We can either use Websockets for this, or use two connections, one for upload and one for download though this involves two requests for every operation and some orchestration on the server side to match one up with the other.

Websockets are a cheaper and simpler way of accomplishing the same thing though sadly the official gRPC implementation has [no plans](https://github.com/grpc/grpc-web/blob/master/doc/streaming-roadmap.md#issues-with-websockets) to implement full-duplex streaming in this way.

This module implements a Websocket proxy for a gRPC-web server.  It's a js port of the [grpcwebproxy](https://github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy) project from [improbable-eng/grpc-web](https://github.com/improbable-eng/grpc-web).

## Protocol

Every RPC invocation opens a new WebSocket connection, the invocation is completed and the socket connection is closed.

The connection is opened against the path of the RPC method the client wishes to invoke.  The path is created from the protobuf service definition package, service and procedure name.

E.g. given the following service definition:

```protobuf
package ipfs;

service Root {
  rpc id (Req) returns (Res) {}
}
```

A path of `/ipfs.Root/id` would be created.

There are three parts to the communication, metadata, messages and trailers.  Communication is symmetrical; that is, the client sends metadata, one or more messages and finally some trailers and the server responds with metadata, one or more messages and finally some trailers.

The amount of messages a client/server can send is dictated by if the RPC method is unary or streaming and if so in which direction.

Unary will result in one message sent and one received, client streaming is many sent and one received, server streaming is one sent and many received and finally bidirectional is many sent and many received.

### 1. Metadata

Metadata is sent as the first websocket message. It is a utf8 encoded list in the same format as [HTTP Headers][]

### 2. Messages

One ore more messages will be sent.  Messages are sent as a single websocket message and contain a signal, a header, some message data and an optional trailer.

Every message sent to or received from the server will have the following format:

| byte index | Notes        |
| ---------- | ------------ |
| 0          | Signal       |
| 1-5        | Header       |
| n1-n2      | Message data |
| n3-n3+5    | Trailer      |

#### Signal

A one-byte field.

| Value | Meaning                                                               |
| ----- | --------------------------------------------------------------------- |
| 0     | START\_SEND: Further messages will be sent as part of this context    |
| 1     | FINISH\_SEND: This is the final message, no further data will be sent |

#### Header

A five-byte field that contains one byte signifying if it's a Header or a Trailer and four bytes that contain the length of the following data.

| byte index | Meaning                                                                        |
| ---------- | ------------------------------------------------------------------------------ |
| 0          | 0: This is a header, 128: This is a footer                                     |
| 1-4        | An unsigned big-endian 32-bit integer that specifies the length of the message |

#### Message data

A protocol buffer message, the length of which is defined in the header

#### Trailer

A five-byte field that contains one byte signifying if it's a Header or a Trailer and four bytes that contain the length of the following data.

| byte index | Meaning                                                              |
| ---------- | -------------------------------------------------------------------- |
| 0          | 0: This is a header, 128: This is a footer                           |
| 1-4        | A big-endian 32-bit integer that specifies the length of the trailer |

The trailer contains [HTTP headers][] as a utf8 encoded string in the same way as invocation metadata.

## Handlers

Method handlers come in four flavours - unary, server streaming, client streaming, bidirectional streaming and accept metadata as an argument.

### Metadata

All methods accept metadata which are sent as the equivalent of HTTP headers as part of every request.  These are accepted by the client as options to a given method.

E.g.:

```js
ipfs.addAll(source, options)
// `source` will be turned into a message stream
// `options` will be sent as metadata
```

### Unary

The simplest case, one request message and one response message.

```javascript
export function grpcFunction (ipfs, options = {}) {
  async function handler (request, metadata) {
    const response = {
      //... some fields here
    }

    return response
  }

  return handler
}
```

### Server streaming

Where the server sends multiple messages.  `sink` is an [it-pushable][].

```javascript
export function grpcFunction (ipfs, options = {}) {
  async function serverStreamingHandler (request, sink, metadata) {
    sink.push(..)
    sink.push(..)

    sink.end()
  }

  return clientStreamingHandler
}
```

### Client streaming

Where the client sends multiple messages.  `source` is an [AsyncIterator][].

```javascript
export function grpcFunction (ipfs, options = {}) {
  async function clientStreamingHandler (source, metadata) {
    const response = {
      //... some fields here
    }

    for await (const thing of source) {
      // do something with `thing`
    }

    return response
  }

  return handler
}
```

### Bidirectional streaming

Where the client and the server both send multiple messages.  `source` is an [AsyncIterator][] and `sink` is an [it-pushable][].

```javascript
export function grpcFunction (ipfs, options = {}) {
  async function bidirectionalHandler (source, sink, metadata) {
    for await (const thing of source) {
      sink.push(sink)
    }

    sink.end()
  }

  return bidirectionalHandler
}
```

## License

Licensed under either of

- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT ([LICENSE-MIT](LICENSE-MIT) / <http://opensource.org/licenses/MIT>)

## Contribute

Contributions welcome! Please check out [the issues](https://github.com/ipfs/js-ipfs/issues).

Also see our [contributing document](https://github.com/ipfs/community/blob/master/CONTRIBUTING_JS.md) for more information on how we work, and about contributing in general.

Please be aware that all interactions related to this repo are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)

[HTTP headers]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers

[it-pushable]: https://www.npmjs.com/package/it-pushable

[AsyncIterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator

---
_Source: https://npm.io/package/ipfs-grpc-server · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
