Giter Club home page Giter Club logo

edge's Introduction

Forking Edge

Fly Edge

npm version isc license Build Status Gitter

The Fly Edge project is a set of APIs for routing HTTP traffic, cache content, and add "middleware" (like auth) to any application. It's written in TypeScript and runs on the Fly Edge runtime. It's built for developers — that means runs locally, has a tests, and integrate into a CI/release pipeline.

The code targets the Service Worker API and uses the Fly runtime API where necessary. You can deploy it to fly.io hosting or run it on any platform with an Edge Service Worker implementation (with reduced features).

Getting Started

Pre-requisites

Try the starter app

git clone https://gist.github.com/ebc48856b74fde392a6d62a032b59a97.git forking-edge
cd forking-edge
yarn install
yarn start # visit http://localhost:3000

Once you have that running, try swapping in a different origin. Edit index.ts and and replace backends.origin("https://getting-started.edgeapp.net") with backends.githubPages("superfly/landing").

Deploy to production

You can deploy edge apps to the Fly hosting service using the CLI. Sign up at fly.io, then run:

yarn fly login
yarn fly app create <name-of-your-app>
yarn fly deploy

You can also run on CloudFlare or StackPath, though not all features will work.

Features

Straightforward TypeScript/ JavaScript API

You can do a lot with a single index.ts file. This example redirects all requests to https and caches content when possible:

import { backends, middleware, pipeline } from "@fly/edge";

// user middleware for https redirect and caching
const mw = pipeline(
  middleware.httpsUpgrader,
  middleware.httpCache
)

// point it at the origin
const app = mw(
  backends.origin("https://getting-started.edgeapp.net")
);

// respond to http requests
fly.http.respondWith(app);

Backends

Backends are origin services you can route requests to. The project includes a backend type any HTTP service, and more specialized types for proxying to third party services.

Want to help out? Write a new backend type and open a pull request!

Middleware

Middleware applies logic to requests before they're sent to the backend, and responses before they're sent to users.

Development

See CONTRIBUTING.

Configuration vs code

The Fly Edge can be run standalone with a yaml based configuration schema. If you prefer to run with a config file, check out the config README.

Who's using it?

  • cars.com: HTTP routing
  • glitch.com: custom domain routing
  • fontawesome.com: CDN for paid customers
  • distractify.com: routing, caching, redirect management
  • greenmatters.com: routing, caching, redirect management
  • artstorefronts.com: custom domain routing
  • kajabi.com: custom domain routing
  • posthaven.com: custom domain routing

edge's People

Contributors

azure-pipelines[bot] avatar barnese3 avatar i8ramin avatar jeromegn avatar kittybot avatar michaeldwan avatar mrkurt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

edge's Issues

Auto-webp middleware

We can make a middleware that automatically encodes images as webp for supported clients.

This would apply to requests with image/webp in the accept header and image/jpeg or image/png in the response type from origin.

queryString problem in `proxy` implementation

Query strings are being ignored in requests.

Example: requests like blah.com/path?stuff are getting sent to backends as just /path

Found with the following code while creating middleware/device-router:

if (deviceType === "mobile" && osName === "Android") {
  const backend = origin({
      origin: `https://play.google.com/store/apps/details?id=${options.android}`,
      headers: {host: "play.google.com"}
  });
  return backend(req);
}

origin is only being seen as https://play.google.com/store/apps/details rather than https://play.google.com/store/apps/details?id=${options.android}

Add Typeform backend

Tried to setup Typeform example form through Fly Sites in UI, but Preview link took me back to https://www.typeform.com/. Could this be because it's a free account and the form is private?

Typeform URL: https://kittybot.typeform.com/to/Su91j4

Middleware: Lazy Loading Images

Middleware feature that will help improve page load time: Lazy Loading — delay the loading of images in long web pages. Images outside of the viewport will not be loaded until the user scrolls to them.

Replace src's with data-image-src tags. Use the IntersectionObserver API to observe when images enter the browsers viewport. When an image comes into view, switch back to src.

For background images, grab their url's and hide/store until image comes into view.

I can get started on this if we think it's a good feature to add.

Custom error middleware

An app should be able to specify which error pages to serve up when it sends an error back to a visitor. A map of status -> file:/// should be enough for a first start at this.

More conventional setup process

The recommended setup process is rather unconventional and difficult to recall without referencing the README. I think a better approach would be for the fly CLI to have a built in generator replicating the project structure in the referenced gist.

Setup might then look something like:

# create fly app, project folder, and `.fly.yml` config
# walk user through setup (similar to `npm init`):
#  - name: example-app
#  - eject (Y/n): y
#  - typescript (Y/n): y
#  - ...
fly apps create

If the user chose not to "eject" their fly app configuration into code upon initial setup, that can still be done later at anytime (prior art: Angular's ng eject):

# code generation based on current `.fly.yml` config
# create webpack, tsconfig, etc if they don't exist (error if they do)
# create/update `package.json` (adding `@fly/cdn` dependency)
# remove `flyCDN` config from `.fly.yml`
fly apps eject --app <name>

Another option, upon ejecting the config, would be to store fly-related configuration in the package.json and eliminate .fly.yml entirely. As an example, babel allows you to do this in place of a .babelrc.js). Would be nice because things like name could be shared between the two.

Analytics middleware

Nothing destroys a lighthouse score like 3rd party tracking scripts. It'd be great if we could offload tracking requests from the client to middleware. Google Analytics is the big one -- are there any other simple integrations? Mixpanel, Heap, Segment?

Google authentication

Protect some routes via a 3rd party auth system (in this case: Google.)

We had that with the old platform (sites), pretty sure it would still be useful.

current `tsconfig.json` throws errors

Not sure if this issue has something to do with my local dev environment, but I was getting tons of TS errors and the only way to fix it was to update my tsconfig.json to the following:

{
  "include": ["./index.ts"],
  "compilerOptions": {
    "target": "es5",
    "lib": ["es2015", "dom"],
    "outDir": "./build/",
    "baseUrl": ".",
    "paths": {
      "@fly/cdn": ["./src/"]
    }
  }
}

AWS S3 Backend type

The CDN should be able to use S3 for storage. The simplest version of this would just use public bucket URLs. The razzle dazzle version should work with private buckets + AWS auth.

Device detection

Feature: device-based caching/dynamic serving

-Using the User-Agent header from requests to deliver cached content based on device type

import { responseCache } from '@fly/cache'

fly.http.respondWith(async function(req) {
	// use "vary: user-agent" header to tell Google that you’re tailoring the content to the User Agent
	req.headers.set("Vary", "User-Agent")

	// get user device type
	let type = req.headers.get("User-Agent").toLowerCase()

	// serve cached or new response based on device type
	if (type.includes("macintosh")) {
		let c = cache("mac", "Hi Mac user!")
		return c

	} else if (type.includes("windows") && !type.includes("mobile")) {
		let c = cache("windows", "Greetings desktop Windows user!")
		return c

	} else if (type.includes("iphone")) {
		let c = cache("iphone", "Howdy iPhone user!")
		return c

	} else if (type.includes("android" && "mobile")) {
		let c = cache("android", "Cheers mobile Android user!")
		return c

	} else {
		let c = cache("device unknown", "Welcome user!")
		return c
	}
})

async function cache(key, response) {
	// create a unique key
	let cacheKey = `${key} version of www.example.com`

	// get cached response if there is one and serve it
	let cachedValue = await responseCache.get(cacheKey)

	if (cachedValue) {
               console.log("response served from cache at key: ", cacheKey)
               return cachedValue
        } else {
              // serve new response and add it to the cache
	     let deviceResponse = new Response(response)
	     await responseCache.set(cacheKey, deviceResponse)
	     return deviceResponse
        }
}

Middleware: redirect www -> non-www host

MIddleware idea/ request: redirect www requests to the same host without www.

Alternatively the same middleware should support redirecting non-www requests to www requests.

Add Squarespace backend

Squarespace should work similarly to Ghost Pro. Most squarespace sites seem to be a subdomain + possible custom domain.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.