Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.2.0 #9

Merged
merged 7 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 8 additions & 15 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,18 @@ name: Unit Tests

on:
push:
branches: [ main ]
branches: [main]
pull_request:
branches: [ main ]
branches: [main]

jobs:
# This workflow contains a single job called "build"
test:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2

# Runs a single command using the runners shell
- name: Install Dependencies
run: yarn

# Runs a set of commands using the runners shell
- name: Runs Test Script
run: yarn test
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 21
- run: npm ci
- run: npm test
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
stable
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021 Duncan Grubbs
Copyright (c) 2024 Duncan Grubbs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
83 changes: 50 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,81 +1,98 @@
![CI](https://github.com/duncangrubbs/ozzy/workflows/CI/badge.svg?event=push)

# 🦘 ozzy
> A small, easy to compose, API interface

Ozzy is a service for interacting with APIs from a Javascript/Typescript client. It is essentially a stripped down version of axios with the inclusion of a middleware feature similar to [Express](https://expressjs.com/) and [axios interceptors](https://axios-http.com/docs/interceptors). It was origionally inspired by this [blog post](https://duncangrubbs.com/blog/oct012020) but has since been updated after more learning on my end. In fact, I recently wrote a new blog post about one of my favorite [uses of middleware](https://duncangrubbs.com/blog/jan122022).
> A small, easy to compose, API interface

If you are building a web app with a modern framework but don't want to install another huge library like axios (almost 400kb!), ozzy is a option to start with, even if you outgrow it eventually.
Ozzy is a interface for interacting with APIs from a Javascript/Typescript client. It is essentially a stripped down version of axios with the inclusion of a middleware feature similar to [Express](https://expressjs.com/) middleware and [axios interceptors](https://axios-http.com/docs/interceptors). It was originally inspired by this [blog post](https://duncangrubbs.com/blog/oct012020) but has since been updated after more learning on my end. In fact, I recently wrote a new blog post about one of my favorite [uses of middleware](https://duncangrubbs.com/blog/jan122022).

## 🤝 Design Principles
1. Lightweight -- _Keep it small, why not?_
2. Easy to Use -- _Simple, straightforward, well-documented functions_
3. Zero Dependencies -- _Outside of dev dependencies, there are no dependencies, so you can get up and running fast in any project_
4. Framework Agnostic -- _Works with any framework_

1. Lightweight
2. Easy to Use
3. Zero Dependencies
4. Framework Agnostic

## 🔨 Docs

### REST Methods

Ozzy is similar to [axios](https://axios-http.com/docs/intro) in that is provides a core set of functions for making HTTP requests. You start by constructing an `Api` for a specific backend service that your client needs to interact with.
```javascript
const userService = new Api(baseUrl, auth, ...middleware)

```typescript
const userService = new Api(baseUrl, authService, ...middleware);
```

You provide the constructor with a `baseUrl`, an authentication service, and an optional collection of middleware functions. This service now has a similar API to axios. For example you can do something like
```javascript
userService
.get('/region/europe')
.then(response => console.log(response))
.catch(error => console.error(error))
You provide the constructor with a `baseUrl`, an authentication service, and an optional collection of middleware functions. If you are writing Typescript, you can also type the API response that will be returned by all API requests. This type can be overridden at the request level though. This service now has a similar API to axios ... for example you can do something like

```typescript
try {
const userResponse = await userService.get<ResponseType>("/region/europe");
} catch (error) {
console.error(error);
}
```

Under the hood this builds the request headers and options, sends the fetch request, applies all of your middleware functions and returns you the final result.
Under the hood this builds the request headers and options, sends the fetch request, applies all of your middleware functions and returns you the final result. Ozzy support all common REST methods

```typescript
Api.get<T>(url: string, ...middleware: any): Promise<T>;
Api.put<T>(url: string, payload: any, ...middleware: any): Promise<T>;
Api.post<T>(url: string, payload: any, ...middleware: any): Promise<T>;
Api.delete<T>(url: string, payload: any, ...middleware: any): Promise<T>;
```

### Auth

Ozzy supports basic auth out of the box. You can configure your auth at the service level by injecting the class into the `Api` constructor. To setup auth for the service, you build an `Auth` object.
```javascript

```typescript
const auth = new Auth(AuthTypes.Bearer, userToken, 'Authorization')

const service = new Api(url, auth...)
```

This code configures the service to send the provided token in the `Authorization` header. The `AuthType` determines the format of this header. In the case the header would look like

```
Authorization: Bearer YOUR_TOKEN
```

### Middleware

At the core of Ozzy is the concept of middleware. This can be applied at the service level or the request level. Middleware intercepts the `Response` object, does something to it, and then passes it to the next middleware. It is important to keep in mind that order matters.
```javascript

```typescript
const middlewareOne = (data, next) => {
// do something to the response data
// of all requests made with this service
return next(data)
}
return next(data);
};

const myService = new Api(
baseUrl,
new Auth(),
middlewareOne
)
const myService = new Api(baseUrl, new Auth(), middlewareOne);

const middlewareTwo = (data, next) => {
// do something to the response data that is
// specific to this request
return next(data)
}
return next(data);
};

myService.get('/api/foo/bar', middlewareTwo).then(data => console.log(data))
const data = await myService.get("/api/foo/bar", middlewareTwo);
```

For those of you who have written a lot of Javascript, you are probably familiar with writing something like this

```javascript
fetch('some url', headers, ...options)
fetch("some url", headers, ...options)
// check the response status code
.then(response => checkStatus(response))
.then((response) => checkStatus(response))
// parse as json
.then(response => response.json())
// finally return the response
.then((response) => response.json());
// finally return the response
```
With Ozzy, you can write a middleware function once, and then apply it at the service level or request level. Out of convenience, ozzy comes with a few middlewares out of the box. Of course it is your choice if you want to apply these middlewares, but they are already written so that you do not have write them yourself. These include a middleware to parse the response as JSON, a basic logger, and a middleware to check the status code of the response and reject the promise if it is outside of the safe range (200-300).

With Ozzy, you can write a middleware function once, and then apply it at the service level or request level. Out of convenience, ozzy comes with a few middlewares out of the box. Of course it is your choice if you want to apply these middlewares, but they are already written so that you do not have write them yourself. These include a middleware to parse the response as JSON, a basic logger, and a middleware to check the status code of the response and reject the promise if the `Response.ok` field is `false`.

## 🙌 Contributing

Feel free to fork and make PRs, they are always welcome! There is a lot of work to do on this project and any help is appreciated. If you don't know where to start you can check out the [issues](https://github.com/duncangrubbs/ozzy/issues) page.
Loading