0.4.0 • Published 5 years ago

@martin_hotell/axios-http v0.4.0

Weekly downloads
-
License
MIT
Repository
github
Last release
5 years ago

axios-http

Injectable axios wrapper for Angular and injection-js 🎯

Greenkeeper badge Build Status NPM version Downloads Standard Version styled with prettier Conventional Commits

Installing

yarn add @martin_hotell/axios-http

# install peer dependencies
yarn add axios injection-js tslib

# install Reflect API polyfill
yarn add @abraham/reflection

Note:

You need a polyfill for the Reflect API.

We highly recommend tiny reflection polyfill ( 3kB only ! )

Also for TypeScript you will need to enable experimentalDecorators and emitDecoratorMetadata flags within your tsconfig.json

Getting started

with injection-js:

import { Injectable, ReflectiveInjector } from 'injection-js'
import {
  registerHttpClientProviders,
  HttpClient,
} from '@martin_hotell/axios-http'

@Injectable()
class UserService {
  constructor(private http: HttpClient) {}

  getUsers() {
    return this.http.get<User[]>('/api/users')
  }
}

const injector = ReflectiveInjector.resolveAndCreate([
  registerHttpClientProviders(),
  UserService,
])

With Angular:

import { Module } from '@angular/core'
import { HttpClientModule, HttpClient } from '@martin_hotell/axios-http'

@Injectable({
  provideIn: 'root',
})
class UserService {
  constructor(private http: HttpClient) {}

  getUsers() {
    return this.http.get<User[]>('/api/users')
  }
}

@Module({
  providers: [HttpClient, HttpClientModule.forRoot()],
})
class AppModule {}

API

axios-http is just a injectable wrapper which creates an axios instance, so API is the same as for axios.instance ( except Interceptors )

Examples

Go checkout examples !

Guides

Type-checking the response

When you execute http.get('/api/user/123').then(response=>response.data), on Success the response object is typeof AxiosPromise<any> with anonymous type of data property. It doesn't know what the shape of that object is.

You can tell HttpClient the type of the response, to make consuming the output easier and more obvious.

First, define an interface with the correct shape:

export interface User {
  name: string
  email: string
}

Then, specify that interface as the HttpClient.get() call's generic type parameter in the service:

getUser(id:string) {
  // now returns a Promise<User>
  return this.http.get<User>(`/api/users/${id}`).then(response => response.data);
}

Now our getUser() returns typed data property as Promise<User>, so we can access our data in type-safe way

heroService.getUser('123').then({name,email}=>...)

Configuring HttpClient

  • when registering providers you can pass optional config to forRoot(config)
import { Injectable, ReflectiveInjector } from 'injection-js'
import { HttpClientModule, HttpClientModule } from '@martin_hotell/axios-http'

@Injectable()
class UserService {
  /*...*/
}

const injector = ReflectiveInjector.resolveAndCreate([
  HttpClientModule.forRoot({
    baseUrl: 'api/swapi',
    withCredentials: true,
  }),
  UserService,
])

Registering Interceptors

axios-http implements similar API for registering interceptors like Angular HttpClient, so you can inject any other service to your interceptors. Under the hood it transforms this API to leverage pure axios ✌️

To wire-up our interceptor, you need to register provider via HTTP_INTERCEPTORS token and set mutli:true:

import { Injectable, ReflectiveInjector } from 'injection-js'
import {
  HttpClientModule,
  HttpInterceptor,
  HTTP_INTERCEPTORS,
  HttpRequest,
  HttpResponse,
} from '@martin_hotell/axios-http'

@Injectable()
class Logger {
  log(...args: any[]) {}
  error(...args: any[]) {}
}

@Injectable()
export class MyInterceptor implements HttpInterceptor {
  // we can inject other injectables
  constructor(private logger: Logger) {}

  interceptRequest(request: HttpRequest) {
    const modifiedData = request.data.replace(/pizza/gi, '🍕')
    const modifiedRequest = { ...request, data: modifiedData }

    return modifiedRequest
  }

  interceptRequestError(error: any) {
    this.logger.error('whooops!')

    return Promise.reject(error)
  }

  interceptResponse(response: HttpResponse) {
    this.logger.log('---> data:', response.data)
    this.logger.log('---> filter:', response.params.get('filter'))

    return response
  }

  interceptResponseError(error: any) {
    this.logger.error('whooops!')

    return Promise.reject(error)
  }
}

const injector = ReflectiveInjector.resolveAndCreate([
  Logger,
  HttpClientModule.forRoot(),
  // wire up our interceptor
  { provide: HTTP_INTERCEPTORS, useClass: MyInterceptor, multi: true },
])

Publishing

Execute yarn release which will handle following tasks:

  • bump package version and git tag
  • update/(create if it doesn't exist) CHANGELOG.md
  • push to github master branch + push tags
  • publish build packages to npm

releases are handled by awesome standard-version

Pre-release

  • To get from 1.1.2 to 1.1.2-0:

yarn release --prerelease

  • Alpha: To get from 1.1.2 to 1.1.2-alpha.0:

yarn release --prerelease alpha

  • Beta: To get from 1.1.2 to 1.1.2-beta.0:

yarn release --prerelease beta

Dry run mode

See what commands would be run, without committing to git or updating files

yarn release --dry-run

Check what files are gonna be published to npm

  • yarn pack OR yarn release:preflight which will create a tarball with everything that would get published to NPM

Tests

Test are written and run via Jest 💪

yarn test
# OR
yarn test:watch

Style guide

Style guides are enforced by robots, I meant prettier and tslint of course 🤖 , so they'll let you know if you screwed something, but most of the time, they'll autofix things for you. Magic right ?

Style guide npm scripts

#Format and fix lint errors
yarn ts:style:fix

Generate documentation

yarn docs

Commit ( via commitizen )

  • this is preferred way how to create convetional-changelog valid commits
  • if you preffer your custom tool we provide a commit hook linter which will error out, it you provide invalid commit message
  • if you are in rush and just wanna skip commit message valiation just prefix your message with WIP: something done ( if you do this please squash your work when you're done with proper commit message so standard-version can create Changelog and bump version of your library appropriately )

yarn commit - will invoke commitizen CLI

Troubleshooting

Licensing

MIT as always

0.4.0

5 years ago

0.3.1

6 years ago

0.3.0

6 years ago

0.2.0

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago