honojs / website

Repository for hono.dev
https://hono.dev
85 stars 281 forks source link

DigitalOcean functions example #458

Open Soviut opened 3 months ago

Soviut commented 3 months ago

It would be great if there was a DigitalOcean functions example.

Their functions seem very simple, with the request being handled by a main(args) entrypoint.

I'm trying to figure out how to call Hono's app.fire() or app.fetch() from this entrypoint but so far no luck.

yusukebe commented 3 months ago

Hi @Soviut

Sounds good. It would be good to place it under https://hono.dev/examples/.

Soviut commented 3 months ago

@yusukebe I was actually thinking it might be good under this Getting Started section since it already covers a lot of different serverless hosts (Deno, Netlify, Vercel, etc.)

image

yusukebe commented 3 months ago

@Soviut

Ah, you're right. It would also be good. By the way, I want to see the actual code for the example to handle DigitalOcean requests and responses.

Soviut commented 3 months ago

@yusukebe

export function main(args: {}): {} {
    const name: string = args['name'] || 'stranger'
    const greeting = 'Hello ' + name + '!'
    return { body: greeting }
}

They have several examples of the functions...

Here is Node https://github.com/digitalocean/sample-functions-nodejs-helloworld/blob/master/packages/sample/hello/hello.js

Here is Typescript https://github.com/digitalocean/sample-functions-typescript-helloworld/blob/master/packages/sample/hello/src/hello.ts

And here is an example of them wrapping Apollo Server https://github.com/digitalocean/sample-functions-apollo-graphql/blob/main/packages/default/graphql/index.ts#L44

In all cases a project.yml file is needed in the root of the project to define the runtime and entrypoint. For example...

packages:
  - name: sample
    actions:
      - name: hello
        runtime: 'nodejs:default'

All of those examples above have a project.yml in their repos.

Soviut commented 3 months ago

Also here are the DigitalOcean docs about Node serverless functions and the args that are sent.

https://docs.digitalocean.com/products/functions/reference/runtimes/node-js/

export function main(event, context) {
  const name = event.name || 'stranger'
  const version = context.functionVersion

  return {
    body: `Hello ${name}! This is version ${version}.`
  }
}

With the event looking like

{
  "http": {
    "headers": {
      "accept": "*/*",
      "accept-encoding": "gzip",
      "user-agent": "curl/7.85.0",
      "x-forwarded-for": "203.0.113.11",
      "x-forwarded-proto": "https",
      "x-request-id": "5df6f6b0d00b58217439c8376fcae23a"
    },
    "method": "POST",
    "path": ""
  },
  "shark": "hammerhead"
}

And the context looking like

{
  "activationId": "5f56b7e9fbd84b2f96b7e9fbd83b2f2e",
  "apiHost": "https://faas-nyc1-2ef2e6cc.doserverless.co",
  "apiKey": "",
  "deadline": 1675959023728,
  "functionName": "/fn-52ad03a2-8660-4f7c-55a5-81aa8bbe73b1/example",
  "functionVersion": "0.0.10",
  "namespace": "fn-52ad03a2-8660-4f7c-55a5-81aa8bbe73b1",
  "requestId": "452164dfeced0a7ad91ee675609024e7"
}
yusukebe commented 3 months ago

@Soviut

Thanks! I saw the code for DegitalOcean; it's interesting. But I wonder if we would need to use Hono for that.

Soviut commented 3 months ago

@yusukebe I already have an API I built with Hono for CloudFlare that I want to move to DIgitalOcean serverless functions on their "App Platform".

Hono is ideal for these "wide" functions (as Supabase likes to call them) where a single function handles all my API requests.

Soviut commented 3 months ago

@yusukebe I managed to get an example working with Hono in a DigitalOcean function.

import { Hono } from 'hono'

const app = new Hono()
app.get('/', (c) => c.text('Hello Node.js!'))

export const main = async (event) => {
  const res = await app.request(event.http.path, { method: event.http.method })
  const body = await res.text()

  return {
    statusCode: res.status,
    body,
  }
}

Obviously this will need more work. Things like passing environment variables from DO to Hono, etc.

yusukebe commented 3 months ago

@Soviut

I managed to get an example working with Hono in a DigitalOcean function.

Ah, I see! That implementation is simple and good. Thank you for sharing it.

Soviut commented 3 months ago

@yusukebe yes, it's straightforward but there should definitely be an official adapter since I'm missing things like headers and such.