Skip to content

Create Next-Gen APIs.do Package #14

@nathanclevenger

Description

@nathanclevenger
  • Minimalistic Code to the theoretical minimum for simple APIs
  • Should support both router-based apps and simple fetch handlers
  • Must have integrated error handling & logging
  • Integrate into updated template.do
import { fetcher, router, db } from 'https://pkg.do/apis.do'

export default {
	fetch: ({api, user, json}) => json({ api, user })
}
import { json, Router } from 'https://pkg.do/apis.do'
const app = new Router()

app.get('/', ({api, user}) => json({ api, user }))
app.get('/:resource', ({api, resource, user}) => json({ api, resource, user }))
app.get('/:resource/:id', ({api, resource, id, user}) => json({ api, resource, id, user }))

export default app

But we should also support an even more concise syntax:

export default {
  api: {
    '/:resource/:id': ({ resource, id }, { api, json, user }) => json({api, resource, id, user })
  }
}

and

export default {
  api: {
    '*': req => fetch('https://api.cf/')
  }
}

the interface is basically routes as the keys under api where the method interface is:

'/': (req, ctx) => new Response('Hello API')

but you should also be able to respond with any object and it creates a JSON serialized response in:

'/': req => ({ hello: 123 })

and if there is an exception it should respond with:

{
  "status": 500
  "error": { "message": "Exception Occurred", "stack": "..." }
}

the ctx object is basically { ...context, ...env, ...ctx } where context is the response from CTX.fetch() and ctx is the arg on the fetch with waitUntil ...

and as a pre-requisite of this we need to get api being dynamically generated in ctx.do ... as well as user ... and if a Response is returned then you can override the default response ... but basically it outputs as json({ api, ...ret, user }) where ret is the response from the method (not being a Response or an Exception)

Additionally ... we can add hostname filters in addition to pathname routing:

export default {
  api: {
    'monaco.do/:url*': ({url}) => fetch(url).then(res => res.text()).then(content => monacoHtml(content)), 
    '*/_/:url*': ({url}) => fetch(url).then(res => res.text()).then(content => monacoHtml(content)), 
  }
}

Then ... I'm thinking we can use workers.do to deploy every build to it's on commit-specific deploy on Workers for SaaS
but ... we can also generate a worker.js in a GitHub action where we dynamically do all of the boilerplate ...

we then don't need ANY IMPORTS
and it could Build in GitHub actions (with no yarn) and Deploy on Cloudflare in 5-10s end to end
we can also support the import if you want ... but if you create an api.js and

export default {
  '*': req => fetch('https://api.cf/')
}

or call it whatever you want ... maybe even specify it as a custom domain ... then it's a file called demo.apis.do.js

export default {
  api: {
    '*': req => ({ hello: 'world!' })
  }
}

then we just need to get cname.do going ... we can tie any domain in that to any worker including dynamic dispatch workers with workers.do and if you don't return a response, we could soft merge the api and user objects so you could set or override properties ...

export default {
  api: {
    '*': req => ({ api: { icon: '🌏' }, hello: 'world!' })
  }
}

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions