Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Grip library for Express and Next.js

License

NotificationsYou must be signed in to change notification settings

fanout/js-serve-grip

Repository files navigation

GRIP library for Node.js, provided asconnect-compatible middleware.

Therefore, this library is usable with frameworks such as the following:

Supported GRIP servers include:

This library also supports legacy services hosted byFanout Cloud.

Authors: Katsuyuki Omurokomuro@fastly.com, Konstantin Bokariuskon@fanout.io

New for v2

Breaking changes

  • Simplified build, now exported as ESM modules only. If you require CommonJS support ora browser build, use v1.
  • A number of classes and interfaces have been removed for simplification.

Introduction

GRIP is a protocol that enables a web service todelegate realtime push behavior to a proxy component, using HTTP and headers.

@fanoutio/serve-grip is a server middleware that works with frameworks such as Express andNext.js. It:

  • gives a simple and straightforward way to configure these frameworks against your GRIP proxy
  • parses theGrip-Sig header in any requests to detect if they came through a Grip proxy
  • provides your route handler with tools to handle such requests, such as:
    • access to information about whether the current request is proxied or is signed
    • methods you can call to issue any instructions to the GRIP proxy
  • provides access to thePublisher object, enabling your application to publish messages throughthe GRIP publisher.

Additionally,serve-grip also handlesWebSocket-Over-HTTP processing sothat WebSocket connections managed by the GRIP proxy can be controlled by your route handlers.

Installation

Install the library.

npm install @fanoutio/serve-grip

Installation in Connect / Express

Import theServeGrip class and instantiate the middleware. Then install it before your routes.

Example:

importexpressfrom'express';import{ServeGrip}from'@fanoutio/serve-grip';constapp=express();constserveGrip=newServeGrip(/* config */);app.use(serveGrip);app.use('/path',(res,req)=>{if(req.grip.isProxied){constgripInstruct=res.grip.startInstruct();gripInstruct.addChannel('test');gripInstruct.setHoldStream();res.end('[stream open]\n');}});app.listen(3000);

Installation in Koa (experimental)

Import theServeGrip class and instantiate it. The Koa middleware is availableas the.koa property on the object. Install it before your routes.

Example:

importKoafrom'koa';importRouterfrom'@koa/router';import{ServeGrip}from'@fanoutio/serve-grip';constapp=newKoa();constserveGrip=newServeGrip(/* config */);app.use(serveGrip.koa);constrouter=newRouter();router.use('/path',ctx=>{if(ctx.req.grip.isProxied){constgripInstruct=res.grip.startInstruct();gripInstruct.addChannel('test');gripInstruct.setHoldStream();ctx.body='[stream open]\n';}});app.use(router.routes()).use(router.allowedMethods());app.listen(3000);

Installation in Next.js

You may use this library to add GRIP functionality to yourNext.js API Routes.

Import theServeGrip class and instantiate the middleware, and then run it in your handlerbefore your application logic by calling the async functionserveGrip.run().

Example:/lib/grip.js:

import{ServeGrip}from'@fanoutio/serve-grip';exportconstserveGrip=newServeGrip(/* config */);

/pages/api/path.js:

import{serveGrip}from'/lib/grip';exportdefaultasync(req,res)=>{// Run the middlewareif(!(awaitserveGrip.run(req,res))){// If serveGrip.run() has returned false, it means the middleware has already// sent and ended the response, usually due to an error.return;}if(req.grip.isProxied){constgripInstruct=res.grip.startInstruct();gripInstruct.addChannel('test');gripInstruct.setHoldStream();res.end('[stream open]\n');}}

Note: In Next.js, you must specifically call the middleware from each of your applicable API routes.This is because in Next.js, your API routes will typically run on a serverless platform, and objectswill be recycled after each request. You are advised to construct a singleton instance of themiddleware in a shared location and reference it from your API routes.

Configuration

@fanoutio/serve-grip/node exports a constructor function,ServeGrip. This constructor takes aconfiguration object that can be used to configure the instance, such as the GRIP proxies to usefor publishing or whether incoming requests should require a GRIP proxy.

Important

ServeGrip is a subclass ofServeGripBase that works withIncomingRequest andServerResponseclasses provided by Node.js.ServeGrip is also available on the main@fanoutio/serve-grip exportwhen the condition"node" is present when resolving imports (the default in Node.js applications).

This design allows non-Node.js platforms (such asExpressly) toextendServeGripBase without holding a dependency on types provided by Node.js.

The following is an example of configuration against Pushpin running on localhost:

import{ServeGrip}from'@fanoutio/serve-grip';constserveGrip=newServeGrip({grip:{control_uri:'https://localhost:5561/',// Control URI for Pushpin publishercontrol_iss:'<issuer>',// (opt.) iss needed for publishing, if required by Pushpinkey:'<publish-key>',// (opt.) key needed for publishing, if required by Pushpin},isGripProxyRequired:true,});

The following is an example of configuration against Fastly Fanout:

import{ServeGrip}from'@fanoutio/serve-grip';constserveGrip=newServeGrip({grip:{control_uri:'https://api.fastly.com/service/<service-id>/',// Control URIkey:'<fastly-api-token>',// Authorization key for publishing (Fastly API Token)verify_iss:'fastly:<service-id>',// Fastly issuer used for validating Grip-Sigverify_key:'<verify-key>',// Fastly public key used for validating Grip-Sig},isGripProxyRequired:true,});

Often the configuration is done using aGRIP_URL (and if needed,GRIP_VERIFY_KEY), allowing for configuration using simple strings. This allows for configuration from environment variables:

GRIP_URL="https://api.fastly.com/service/<service-id>/?verify-iss=fastly:<service-id>&key=<fastly-api-token>"GRIP_VERIFY_KEY="base64:LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFQ0tvNUExZWJ5RmNubVZWOFNFNU9uKzhHODFKeQpCalN2Y3J4NFZMZXRXQ2p1REFtcHBUbzN4TS96ejc2M0NPVENnSGZwLzZsUGRDeVlqanFjK0dNN3N3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t"
import{ServeGrip}from'@fanoutio/serve-grip';constserveGrip=newServeGrip({grip:process.env.GRIP_URL,gripVerifyKey:process.env.GRIP_VERIFY_KEY,isGripProxyRequired:true,});

Available options:

KeyValue
gripA definition of GRIP proxies used to publish messages, or a preconfigured Publisher object from@fanoutio/grip. See below for details.
gripVerifyKey(optional) A string or Buffer that can be used to specify theverify-key component of the GRIP configuration.
Applies only if -
*grip is provided as a string, configuration object, or array of configuration objects
*grip does not already contain averify_key value.
gripProxyRequired(optional) A boolean value representing whether all incoming requests should require that they be called behind a GRIP proxy. If this is true and a GRIP proxy is not detected, then a501 Not Implemented error will be issued. Defaults tofalse.
prefix(optional) A string that will be prepended to the name of channels being published to. This can be used for namespacing. Defaults to''.

In most cases your application will construct a singleton instance of this class and use it asthe middleware.

Thegrip parameter may be provided as any of the following:

  1. An object with the following fields:

    FieldDescription
    control_uriThe Control URI of the GRIP client.
    control_iss(optional) The Control ISS, if required by the GRIP client.
    key(optional) string or Buffer. The key to use with the Control ISS, if required by the GRIP client.
    verify_iss(optional) The ISS to use when validating a GRIP signature.
    verify_key(optional) string or Buffer. The key to use when validating a GRIP signature.
  2. An array of such objects.

  3. A GRIP URI, which is a string that encodes the above as a single string.

  4. (advanced) APublisher object that you have instantiated and configured yourself, from@fanoutio/grip.

Handling a route

After the middleware has run, your handler will receivereq andres objects that have beenextended withgrip properties. These provide access to the following:

KeyDescription
req.grip.isProxiedA boolean value indicating whether the current request has been called via a GRIP proxy.
req.grip.isSignedA boolean value indicating whether the current request is a signed request called via a GRIP proxy.
req.grip.wsContextIf the current request has been made through WebSocket-Over-HTTP, then aWebSocketContext object for the current request. See@fanoutio/grip for details onWebSocketContext.
KeyDescription
res.grip.startInstruct()Returns an instance ofGripInstruct, which can be used to issue instructions to the GRIP proxy to hold connections. See@fanoutio/grip for details onGripInstruct.

To publish messages, callserveGrip.getPublisher() to obtain aPublisher. Use it to publish messages using the endpoints andprefix specified to theServeGrip constructor.

KeyDescription
serveGrip.getPublisher()Returns an instance ofPublisher, which can be used to publish messages to the provided publishing endpoints using the provided prefix. See@fanoutio/grip for details onPublisher.

Examples

This repository contains examples to illustrate the use ofserve-grip in Connect / Expressand Next.js, which can be found in theexamples directory. For details on each example, pleaseread theREADME.md files in the corresponding directories.

Advanced

Next.js alternative invocation

As an alternative method of runningserveGrip in a Next.js API route, sinceserveGrip isconnect-compatible, you may use the process described inAPI Middlewares.This may be useful for example if you have multiple middlewares and you wish to call them in auniform manner.

Example:/lib/grip.js:

import{ServeGrip}from'@fanoutio/serve-grip';exportconstserveGrip=newServeGrip(/* config */);// Helper method to wait for a middleware to execute before continuing// And to throw an error when an error happens in a middleware// https://nextjs.org/docs/api-routes/api-middlewares#connectexpress-middleware-supportexportfunctionrunMiddleware(req,res,fn){returnnewPromise((resolve,reject)=>{fn(req,res,(result)=>{if(resultinstanceofError){returnreject(result)}returnresolve(result)})})}

/pages/api/path.js:

import{serveGrip,runMiddleware}from'/lib/grip';exportdefaultasync(req,res)=>{// Run the middlewareawaitrunMiddleware(req,res,serveGrip);if(req.grip.isProxied){constgripInstruct=res.grip.startInstruct();gripInstruct.addChannel('test');gripInstruct.setHoldStream();res.end('[stream open]\n');}}

Changes fromexpress-grip

If you have usedexpress-grip in the past, you will notice that this library no longerrequires the use of pre-route and post-route middlewares. Consequently, you do not need tocallnext() for route handlers that complete their work. In fact, you should follow thestandard practice of callingres.end() at the end of each of your route handlers.

License

(C) 2015, 2020 Fanout, Inc.
(C) 2024 Fastly, Inc.Licensed under the MIT License, see file LICENSE.md for details.

About

Grip library for Express and Next.js

Resources

License

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp