Skip to content

apicase/services

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Oct 3, 2018
08c6e56 · Oct 3, 2018

History

74 Commits
Apr 29, 2018
Mar 11, 2018
Apr 29, 2018
Apr 29, 2018
Oct 5, 2017
Jun 19, 2018
Oct 3, 2018
Mar 12, 2018
Mar 12, 2018
Oct 3, 2018
Mar 11, 2018
May 9, 2018

Repository files navigation

Apicase services

Powerful API layer based on @apicase/core

Full documentation

Quick start with Apicase
Apicase services

Installation

yarn add @apicase/services
npm install @apicase/services

Create service

import fetch from '@apicase/adapter-fetch'
import { ApiService } from '@apicase/services'

const SomeService = new ApiService({
  adapter: fetch,
  url: '/api/posts'
  method: 'GET'
})

// { "url": "/api/posts", "method": "GET", "query": { "userId": 1 } }
SomeService.doRequest({
  query: { userId: 1 }
})

ApiTree

To reduce boilerplate code, you can declare your services as JSON object

import { ApiTree } from '@apicase/services'

const api = new ApiTree([
  { url: '/api', children: [
    { url: 'posts', children: [
      { name: 'getAllPosts',   url: '',    method: 'GET'    },
      { name: 'createPost',    url: '',    method: 'POST'   },
      { name: 'getOnePost',    url: ':id', method: 'GET'    },
      { name: 'updateOnePost', url: ':id', method: 'PUT'    },
      { name: 'removeOnePost', url: ':id', method: 'REMOVE' }
    ] },
    { url: 'profile', children: [...] }
  ] }
])

api('getAllPosts').doRequest()
api('createPost').doRequest({ body })

Parent service

You can also pass parent service instead of adapter. It may flatten structure

const Root = new ApiService(fetch, { url: '/api' })

const api = new ApiTree(Root, [
  { url: 'posts', children: [
    { name: 'getAllPosts',   url: '',    method: 'GET'    },
    { name: 'createPost',    url: '',    method: 'POST'   },
    { name: 'getOnePost',    url: ':id', method: 'GET'    },
    { name: 'updateOnePost', url: ':id', method: 'PUT'    },
    { name: 'removeOnePost', url: ':id', method: 'REMOVE' }
  ] },
  { url: 'profile', children: [...] }
])

Shorter requests

api("someService", payload) === api("someService").doRequest(payload)

ApiObjectTree helper

Alternative way to avoid string api (but there are no children option):

import { ApiObjectTree } from '@apicase/services'

const api = new ApiTree(BaseService, {
  getAllPosts: { url: '' },
  createPost:  { url: '',    method: 'POST' },
  getOnePost:  { url: ':id', method: 'POST' },
  updOnePost:  { url: ':id', method: 'PUT' },
  rmvOnePost:  { url: ':id', method: 'DELETE' }
})

api.getAllPosts.doRequest()
api.createPost.doRequest({ body })

rest and wrappedRest helpers

Helper to work with REST APIs just automatically generates urls, methods and names

import { ApiTree, rest } from "@apicase/services"

/*
  If you are lucky - default structure doesn't need to write URL's
  postsGetAll: GET    /
  postsGetOne: GET    /:id
  postsCreate: POST   /
  postsUpdOne: PUT    /:id
  postsRmvOne: DELETE /:id
*/
const posts = rest("posts", ["getAll", "getOne", "create", "updOne", "rmvOne"])

/* Skip 2nd argument to get just all routes */
const posts = rest("posts")

/* Otherwise, still OK */
const profile = rest("profile", {
  getAll: { url: "we/have" },
  create: { url: "custom/routes" },
  getOne: { url: "no_refactoring/:id" },
  updOne: { url: "since_2008/:id" },
  rmvOne: { url: "legacy_shit" }
})

new ApiTree(Root, [
  { url: "posts", children: posts },
  { url: "profile", children: profile }
])

wrappedRest helper is similar to rest but also wraps it into url with name:

import { ApiTree, wrappedRest } from "@apicase/services"

new ApiTree(Root, [wrappedRest("posts"), wrappedRest("profile")])

License

MIT © Anton Kosykh