DEV Community

Akash Kava for Web Atoms

Posted on • Updated on

RetroFit inspired REST Services in Web Atoms Core

Service Declaration

@DISingleton()
@BaseUrl("/api/v2020/app/")
export default class TaskService extends BaseService {

    @Get("user")
    public getUser(): Promise<IUser>;

    @Get("tasks")
    public getTasks(
        @Query("search") search: string,
        // default value should be specified in
        // decorator and not in argument declaration
        @Query("status", "open") status?: string
    ): Promise<ITask[]>

    @Get("tasks/{id}/attachments")
    public getAttachments(
        @Path("id") id: number
    ): Promise<ITaskAttachment[]>;

    @Put("tasks")
    public createTask(@Body task: ITask): Promise<ITask>;

    @Post("tasks/{id}/attachments")
    public uploadAttachment(
        @Path("id") id: number,
        @Body att: IAttachment,
        cancelToken: CancelToken): Promise<void>;
}
Enter fullscreen mode Exit fullscreen mode

As easy as it looks, its very easy to configure REST service.

Caching

    @Get("tasks", { jsCacheSeconds: 900 })
    public getTasks(
        @Query("search") search: string,
        // default value should be specified in
        // decorator and not in argument declaration
        @Query("status", "open") status?: string
    ): Promise<ITask[]>
Enter fullscreen mode Exit fullscreen mode

Caches response in JavaScript for 900 seconds.

Caching based on result

    @Get("tasks", { jsCacheSeconds: (r) => r.length ? 900 : 0 })
    public getTasks(
        @Query("search") search: string,
        // default value should be specified in
        // decorator and not in argument declaration
        @Query("status", "open") status?: string
    ): Promise<ITask[]>
Enter fullscreen mode Exit fullscreen mode

Cache response only if returned array has any items.

Fixed Headers

    @Get("tasks", {
            headers: {
               "x-cache": "none",
               "accept": "application/json"
            }
    })
    public getTasks(
        @Query("search") search: string,
        // default value should be specified in
        // decorator and not in argument declaration
        @Query("status", "open") status?: string
    ): Promise<ITask[]>
Enter fullscreen mode Exit fullscreen mode

Header in Parameters

    @Get("tasks")
    public getTasks(
        @Header("x-auth") auth: string,
        @Query("search") search: string,
        // default value should be specified in
        // decorator and not in argument declaration
        @Query("status", "open") status?: string
    ): Promise<ITask[]>
Enter fullscreen mode Exit fullscreen mode

Json Parsing Options

    @Get("tasks", { 
       jsonOptions: {
          namingStrategy: "underscore",
          indent: 2,
          dateConverter: {
             regex: dateFormatRegex,
             valueConverter: {
                fromSource:(v: string) => Date,
                fromTarget:(date: Date) => string
             }
          }
       }
    })
    public getTasks(
        @Header("x-auth") auth: string,
        @Query("search") search: string,
        // default value should be specified in
        // decorator and not in argument declaration
        @Query("status", "open") status?: string
    ): Promise<ITask[]>
Enter fullscreen mode Exit fullscreen mode

Returning Headers !!

    @Get("tasks", { 
       returnHeaders: true
    })
    public getTasks(
        @Header("x-auth") auth: string,
        @Query("search") search: string,
        // default value should be specified in
        // decorator and not in argument declaration
        @Query("status", "open") status?: string
    ): Promise<IApiResponse<ITask[]>>
Enter fullscreen mode Exit fullscreen mode

The only difference is, result type is always IApiResponse<T>, which contains headers and value.

Mocking

Mocking services makes unit testing and design time development very easy.

@DISingleton({ mock: "./mocks/MockTaskService" })
@BaseUrl("/api/v2020/app/")
export default class TaskService extends BaseService {
...
Enter fullscreen mode Exit fullscreen mode

Now you can keep MockTaskService inside mocks folder. And override every method to return design time data.

Dive into samples

https://www.webatoms.in/samples.html#contextId=0

GitHub logo web-atoms / core

MVVM Framework for JavaScript for Browser, Xamarin.Forms, Write TSX/TypeScript instead of Xaml and C#, Hot Reload Live Published Xamarin.Forms Apps.

Action Status npm version codecov

Web-Atoms Core

Web Atoms Core is a UI abstraction framework along with powerful MVVM pattern to design modern web and mobile applications.

Xamarin.Forms Features

  1. Use VS Code to develop Xamarin.Forms
  2. Write TypeScript instead of C#
  3. Write TSX (JSX) instead of Xaml
  4. Live hot reload for published app

Web Features

  1. Abstract Atom Component
  2. Abstract Device API (Browser Service, Message Broadcast)
  3. Theme and styles support without CSS
  4. One time, One way and Two way binding support
  5. Simple dependency Injection
  6. In built simple unit testing framework
  7. UMD module support
  8. Full featured MVVM Framework with powerful validation

Folder structure

  1. All views for web must be placed under "web" folder inside "src" folder.
  2. All views for Xamarin Forms must be placed under "xf" folder inside "src" folder.

Example folder structure

src
+--images
|  +--AddButton.svg
|
+--view-Models
|  +--TaskListViewModel.ts
|  +--TaskEditorViewModel.ts
|
+--web
|  +--tasks
|     +--TaskListView.tsx
|     +--TaskEditorView.tsx
|
+--xf
   +--tasks
      +--TaskListView.tsx
      +--TaskEditorView.tsx

Example View

Top comments (0)