fable.remoting.ts
TypeScript icon, indicating that this package has built-in type declarations

0.6.0 • Public • Published

Fable.Remoting.Ts

CI npm version

This is a simple proxy-based library that tries to help you interact with your .net server in a simple way.

Fable.Remoting is one incredibly nice way to interact with your server where you define your types in a shared project/file and then you just invoke functions based on those declared types.

Sometimes you won't be able (or don't want to) use F# as the client of your F#/C# server and that sadly takes some of the Fable.Remoting Advantages away (apparently) if you enable raw http in Fable.Remoting, then you can use this library to ease some of those interactions

Requirements

This library uses ES2015 Proxy so there's no IE support it also uses Axios and msgpack.js so it should be usable both in your browser and any node.js environment

Usage

you can also check a sample here and here

import { createService } from 'fable.remoting.ts'

const service = createService({ 
    // where is your server at?
    baseURL: 'http://localhost:5000',
    // this is the name of the service you registered within your server
    serviceName: 'IBooksService',
    // wether your server is sending msgpack messages
    withMsgPack: false
});

// use getBooks anywhere else
const getBooks = async () => {
    //the name of the service method you want to invoke on the server
    try {
        const results = await service.getBooks();
        return results;
    } catch(error) {
        console.warn(error.message);
        return [];
    }
}

// use saveBook somewhere else
const saveBook = async (book: Book)  => {
    try {
        const results = await service.saveBook(book);
        return results;
    } catch(error) {
        console.warn(error.message);
        throw Error(error);
    }
}

type safety

If you want to have a little bit more of type safety you might want to create an interface/type that represents what your server is doing for you (what you would normally do with F# types)

interface IBooksService {
    getBooks: () => Promise<AxiosResponse<Book[]>>;
    saveBook: (book: Bool) => Promise<AxiosResponse<Book>>;
}

const service = createService<IBooksService>({ 
    // where is your server at?
    baseURL: 'http://localhost:5000',
    // this is the name of the service you registered within your server
    serviceName: 'IBooksService',
    // wether your server is sending msgpack messages
    withMsgPack: false
});

// now you have typescript autocompletition
const { data } = await service.getBooks();
// typescript will complain about this
// service.IDontExist()
// although if you cast service as "any" it will still try to make the call to
// http://localhost:5000/IBooksService/IDontExist
// (service as any).IDontExist()
// so if you are using pure javascript where typos can slip through be careful about this

Extra configuring

If you want to customize further your http calls, you can pass axios options to your createService call, each createService call provides you with an axios instance

const service = createService<IBooksService>(
    { 
        // where is your server at?
        baseURL: 'http://localhost:5000',
        // this is the name of the service you registered within your server
        serviceName: 'IBooksService',
        // wether your server is sending msgpack messages
        withMsgPack: false
    }, 
    {
        headers: { /* ... any header you want to add ...*/ }
        proxy: { /* ... proxy options ... */},
        xsrfCookieName: 'cookie name',
        // ... and any other AxiosRequest options
    }
);

If you need to provide a new header (or delete) to an existing service instance, you can call

  • addHeaders
  • removeHeaders
  • addInterceptors
  • removeInterceptors methods accordingly
service.addHeaders({ 
    /* ... any headers you want to add here ...*/
    Authorization: 'Bearer ...token...'
});
// removeHeaders accepts any amount of string parameters
service.removeHeaders('Authorization', 'x-my-custom-header', ...myOtherHeaders);
//interceptors
 const id = service.addInterceptor('request', function logger(v: any) {
        console.log(v);
        return v;
    });

service.removeInterceptor(id);

Augment an existing service

You can use an existing service that is not made by Fable.Remoting.Ts, perhaps you already have services in place and want to add those extra functions

type IExistingService = {
    somePropertyForSomeReason: string;
    login(username: string; password: string) => Promise<AuthResponse>;
    Signup(user: SignupPayload) => Promise<AuthResponse>;
};

const existingService: IExistingService = createFromDIOrSomewhereElse();

const service = createService<IExistingService & IBooksService>({ 
    // where is your server at?
    baseURL: 'http://localhost:5000',
    // this is the name of the service you registered within your server
    serviceName: 'IBooksService',
    // whether your server is sending msgpack messages
    withMsgPack: false
}, null, existingService);

/**
 * For example let's try to login (existing service)
 * and get books (from proxy service) with a jwt token as authorization.
 **/
async function loginAndGetBooks() {
    // service will pick the login method from `existingService`
    const { token } = await service.login('admin@admin.com', 'super secret much wow')
    service.addHeaders({ Authorization: `Bearer ${token}` })
    // service will pick the getBooks method from the default proxy trap
    const books = await service.getBooks()
    console.log(books)
    // service will pick the somePropertyForSomeReason property from the `existingService` object
    console.log(service.somePropertyForSomeReason)
}

Craft your own request

if nothing of the above works for you for a specific use case, you can always fallback to axios's custom requests

const service = createService({ 
    // where is your server at?
    baseURL: 'http://localhost:5000',
    // this is the name of the service you registered within your server
    serviceName: 'IBooksService'
});

const response = await service.createRequest<MyOtherAPIResponse>({
        url: 'http://my.other.api.com',
        method: 'DELETE',
        params: {
            hello: 'world'
        }
    });
console.log(response.data);

Package Sidebar

Install

npm i fable.remoting.ts

Weekly Downloads

0

Version

0.6.0

License

ISC

Unpacked Size

18 kB

Total Files

6

Last publish

Collaborators

  • tunaxor