Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/hodgef/apiker
πΌ Create Serverless APIs with Cloudflare Workers, Durable Objects & Wrangler
https://github.com/hodgef/apiker
api cloudflare-workers durable-objects jwt wrangler
Last synced: 2 days ago
JSON representation
πΌ Create Serverless APIs with Cloudflare Workers, Durable Objects & Wrangler
- Host: GitHub
- URL: https://github.com/hodgef/apiker
- Owner: hodgef
- License: mit
- Created: 2021-11-04T02:40:33.000Z (almost 3 years ago)
- Default Branch: master
- Last Pushed: 2024-04-20T00:36:24.000Z (7 months ago)
- Last Synced: 2024-10-13T08:43:13.732Z (22 days ago)
- Topics: api, cloudflare-workers, durable-objects, jwt, wrangler
- Language: TypeScript
- Homepage: http://hodgef.com/apiker
- Size: 2.1 MB
- Stars: 113
- Watchers: 3
- Forks: 6
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
## π¦ Installation & Usage
With Apiker, you can create an API in only 3 lines of code
```js
import { apiker, res } from "apiker";
const routes = { "/users/:id/hello": () => res("Hello World!") };apiker.init({ routes, exports, objects: ["Common"] });
```
> β‘οΈ GET /users/my-user/hello
```
{ "message": "Hello World!" }
```Check out the **[Getting Started](https://hodgef.com/apiker/)** page to begin.
Note: To run Apiker, you need a Cloudflare account with [Durable Objects access](https://developers.cloudflare.com/workers/platform/pricing#durable-objects).
## β Features
- π Routing and State management
- π Auth, JWT-based (Register, Login, Refresh token, Delete user, Forgot user, Verify user email)
- β OAuth handlers (GitHub)
- β‘οΈAutomatically updates [Durable Object](https://developers.cloudflare.com/workers/learning/using-durable-objects) migrations, classes and bindings so you don't have to.
- π Rate Limiting / Flooding mitigation
- π‘οΈ Firewall support (IP bans with Cloudflare Firewall)
- π§ Email support (with [Brevo](https://www.brevo.com/products/transactional-email/))
- βοΈ Simple Admin panel
- π€ Geolocation handlers
- π Logging handlers## π Examples
### 1. Route example
```js
import { res, res_400 } from "apiker";export const myRouteHandler = async ({
request, // https://developers.cloudflare.com/workers/runtime-apis/request/
body, // The body of your request, such as form params or plaintext, depending on request content-type
headers, // Request headers. Response headers are located at `apiker.responseHeaders`
matches, // Your query params and route parts
state // The state method used to interact with permanent storage (check the examples below & docs for more info)
}) => {
// If we want to allow POST only, we explicitly check for it :
if(request.method !== "POST"){
// returns 400 Bad Request error. You can also use `res("Invalid Method", 405)`
// https://github.com/hodgef/apiker/blob/master/src/components/Response/Response.ts#L10
return res_400();
}// We'll return the request body passed, for example POST form parameters
// `res` and `res_000` functions respond with JSON. To respond with raw text you can use `resRaw`
// https://github.com/hodgef/apiker/blob/master/src/components/Response/Response.ts#L23
return res({ body });
};
```
```js
const routes = {
"/users/myroute": myRouteHandler
};
```
Discuss: https://github.com/hodgef/apiker/issues/133### 2. State: Save value to `Common` object (shared by all visitors)
```js
import { res } from "apiker";export const example1_saveValueCommon = async ({ state }) => {
// Using `state` with no parameters will default to the Common object
const count = ((await state().get("count")) || 0) + 1;
await state().put({ count });
return res({ count });
};
```
> β‘οΈ GET /example1
```
{ "count": 1 }
```
[View Source](https://github.com/hodgef/apiker-examples/blob/master/src/controllers/example1_saveValueCommon.ts) | [View Demo](https://apiker-examples.volted.co/example1)### 3. State: Save value to a different object, and use one object instance per visitor
```js
import { res } from "apiker";export const example2_saveValueDiffObject = async ({ state }) => {
const count = (await state("Example2").get("count") || 0) + 1;
await state("Example2").put({ count });
return res({ count });
};// In index.js ...
apiker.init({
...
objectStateMapping: {
// One object instance per user IP
Example2: OBMT.SIGNEDIP
}
});
```
> β‘οΈ GET /example2
```
{ "count": 1 }
```
[View Source](https://github.com/hodgef/apiker-examples/blob/master/src/controllers/example2_saveValueDiffObject.ts) | [View Demo](https://apiker-examples.volted.co/example2)### 4. State: Use one object instance per route parameter value
```js
import { res } from "apiker";export const example3_instancePerRouteParam = async ({ state, matches }) => {
// Get username from route (/example3/:username)
const username = matches.params.username;
const acceptedUsernames = ["bob", "rob", "todd"];if (acceptedUsernames.includes(username)) {
const { name = username, count = 0 } = (await state("Example3").get("username")) || {};
const payload = {
username: {
name,
count: count + 1
}
};await state("Example3").put(payload);
return res(payload);
} else {
return res({ acceptedUsernames });
}
};// In index.js ...
apiker.init({
...
objectStateMapping: {
// Mapped to the parameter `username` in the route
Example3: "username"
}
});
```
> β‘οΈ GET /example3/bob
```
{
"username": {
"name": "bob",
"count": 1
}
}
```
[View Source](https://github.com/hodgef/apiker-examples/blob/master/src/controllers/example3_instancePerRouteParam.ts) | [View Demo](https://apiker-examples.volted.co/example3/bob)> For more details and examples, check out the **[Documentation](https://hodgef.com/apiker/)**.
## β Contributing
PRs and issues are welcome. Feel free to submit any issues you have at:
[https://github.com/hodgef/Apiker/issues](https://github.com/hodgef/Apiker/issues)### Questions? Join the chat