Skip to content

Version6 : correct work with latest version of Angular + edit response. #2

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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
node_modules
node_modules
/test-api/node_modules/
/dist

*.lock
4 changes: 4 additions & 0 deletions .metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"skipMetadataEmit": true,
"skipTemplateCodegen": true
}
51 changes: 37 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
# ngx-http-rest
# ngx-http-annotations

This library allows to interact with rest api in your angular app.
It contains:

- Annotations for http methods (@GET, @POST, @PUT, @DELETE, @OPTIONS, @HEAD, @PATCH)
- Annotations for adding headers, setting produces results and intercepting response
- Params anotations
- Params annotations

forked from : https://github.com/Mixalloff/ngx-http-rest

### Installation

Install through npm:

```sh
$ npm install ngx-http-rest --save
$ npm install ngx-http-annotations --save
```


Expand All @@ -23,7 +25,7 @@ Example of using library.
1) Plug the HttpRestModule into your AppModule

```typescript
import { HttpRestModule } from 'ngx-http-rest';
import { HttpRestModule } from 'ngx-http-annotations';
import { NgModule } from '@angular/core';

@NgModule({
Expand All @@ -39,7 +41,7 @@ export class AppModule {


```typescript
import { HttpRestService, GET, Path, PathParam, QueryParam, QueryParams } from 'ngx-http-rest';
import { HttpRestService, GET, POST, DELETE, Path, PathParam, Body, QueryParam, QueryParams, ResponseObservable } from 'ngx-http-annotations';
import { Injectable } from '@angular/core';
import RestConfig from 'app/core/configs/rest.config';

Expand Down Expand Up @@ -71,7 +73,6 @@ export class SomeRestService extends HttpRestService {
getGoodsItemById(@PathParam('id') itemId: number): any {}

@GET
@Interceptor(SomeRestService.logInterceptor) /* Set response interceptor */
@Path('/:id/child/:childId') /* Few path params */
getChildrenOfSomeGoods(@PathParam('id') id: number,
@PathParam('childId') childId: number
Expand All @@ -83,14 +84,19 @@ export class SomeRestService extends HttpRestService {
createGoods(@Body /* Body of POST request */ goodsObject: GoodsItem): any {}

@DELETE
@NoResponse /* This method doesn`t process the body of response */
@Path('/:id')
removeGoodsById(@PathParam('id') itemId: number): any {}

private static logInterceptor(response: any) {
console.log(response);

@GET
@Path('posts')
/**
* getPostForUserId(3, 2) : call the the url /posts?userId=2 and only take 3 results
*/
public getPostForUserId(number: number, @QueryParam('userId') userId: number, @ResponseObservable res: Observable<any> = undefined): Observable<any> {
return res.pipe(map((response) => response.slice(0, number)));
}


}
```

Expand Down Expand Up @@ -125,10 +131,27 @@ Available annotations:
- @Path - set path of url for request. Combined class @Path annotation value and current method @Path. Path params passed with ":". For example @Path('/someurl/:someParam')
- @Headers - set headers for request (if annotate class, then all class methods getting this headers. method Headers merge with class Headers)
- @Produces - setting expected response type. By default Reponse transformed by .json() method
- @NoResponse (alias for @Produces(null)) - if expected empty response body, you need to set that annotation
- @DefaultResponse (alias for @Produces(Response)) - response doesn`t transformed with .json() method. Returned pure Response object
3) Parameters
- @Observes - setting http observes.
3) Parameters
- @PathParam (or @Path) - pass current parameter by name to collected url. Example: someFunc(@PathParam('id') itemId: number) {}
- @Body - pass body object into request. Ex.: someMethod(@Body bodyObject: any){}
- @QueryParam - pass single query parameters into request. Ex.: someMethod(@QueryParam('a') a: any, @QueryParam('b') b: any) {}. someMethod(1, 2) -> ..requested_url..?a=1&b=2
- @QueryParams - pass object with few query params. Ex.: someMethod(@QueryParams queryObj: any){}. someMethod({x: 1, y: 2, z: 3}) -> ..requested_url..?x=1&y=2&z=3
- @QueryParams - pass object with few query params. Ex.: someMethod(@QueryParams queryObj: any){}. someMethod({x: 1, y: 2, z: 3}) -> ..requested_url..?x=1&y=2&z=3
- @ResponseObservable - specify in witch function params, the response observable will be added. Ex.: someMethod(@ResponseObservable res: Observable<any> = undefined){ /* transform request */ return res; }. need to initialise as undefined to pass compile error, and return a response.


#### Transform response with all rxjs function

By adding the parameters @ResponseObservable you can specify, where add the observable response,

```typescript

@GET
@Path('posts')
/**
* getPostForUserId(3, 2) : call the the url /posts?userId=2 and only take 3 results
*/
public getPostForUserId(number: number, @QueryParam('userId') userId: number, @ResponseObservable res: Observable<any> = undefined): Observable<any> {
return res.pipe(map((response) => response.slice(0, number)));
}
```
17 changes: 17 additions & 0 deletions ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "ngx-http-annotations",
"version": "0.5.2",
"$schema": "./node_modules/ng-packagr/ng-package.schema.json",
"src": "src",
"dest": "dist/ngx-http-annotations",
"workingDirectory": ".ng_build",
"lib": {
"entryFile": "public_api.ts"
},
"ngPackage": {
"lib": {
"entryFile": "public_api.ts"
}
}

}
44 changes: 35 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,47 @@
{
"name": "ngx-http-rest",
"version": "0.4.0",
"name": "ngx-http-annotations",
"version": "0.6.1",
"main": "public_api.ts",
"files": [
"src"
],
"scripts": {
"build": "ng-packagr -p ng-package.json"
},
"directories": {
"src": "src"
},
"devDependencies": {
"@angular/http": "^4.0.0",
"@angular/core": "^4.0.0",
"rxjs": "^5.0.1",
"typescript": "^2.2.2"
"@angular-devkit/build-angular": "~0.6.0",
"@angular-devkit/schematics": "^0.6.0",
"@angular/cli": "6.0.5",
"@angular/common": "6.0.3",
"@angular/compiler": "6.0.3",
"@angular/compiler-cli": "6.0.3",
"@angular/core": "6.0.3",
"@angular/forms": "6.0.3",
"@angular/http": "6.0.3",
"@angular/language-service": "6.0.3",
"@angular/platform-browser": "6.0.3",
"@angular/platform-browser-dynamic": "6.0.3",
"@angular/router": "6.0.3",
"core-js": "^2.4.1",
"ng-packagr": "^4.4.0",
"rxjs": "^6.0.0-beta.1",
"typescript": "2.7.2",
"zone.js": "0.8.26"
},
"author": "Mixalloff",
"author": "Mixalloff, manudss",
"keywords": [
"angular",
"ng2",
"ngx",
"http",
"rest",
"annotations",
"annotations",
"api"
],
"license": "MIT",
"repository": "https://github.com/Mixalloff/ngx-http-rest"
}
"repository": "https://github.com/manudss/ngx-http-annotations"
}
10 changes: 5 additions & 5 deletions index.ts → public_api.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
export * from './src/ngx-http-rest.module';
import { Response } from '@angular/http';
import { HttpRestUtils, path, body, query, headers, produces, observe } from "ngx-http-rest/src/ngx-http-rest.utils";
export * from './src/ngx-http-annotations.module';
export * from './src/ngx-http-annotations.utils';
import {HttpRestUtils, path, body, query, headers, produces, observe, response} from "./src/ngx-http-annotations.utils";

export let Path = path;
export let PathParam = path;
export let Body = body(null);
export let ResponseObservable = response(null);
export let Query = query(null);
export let QueryParam = query;
export let QueryParams = query(null);
export let Observe = observe;

// Headers
Expand All @@ -17,7 +17,7 @@ export let Headers = headers;
export let Produces = produces;

// Request methods
export const GET = HttpRestUtils.requestMethod('Get')
export let GET = HttpRestUtils.requestMethod('Get');
export let POST = HttpRestUtils.requestMethod('Post');
export let PUT = HttpRestUtils.requestMethod('Put');
export let DELETE = HttpRestUtils.requestMethod('Delete');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { HttpRestUtils } from "./ngx-http-rest.utils";
import {NgModule, APP_INITIALIZER, Inject} from '@angular/core';
import { HttpRestUtils } from "./ngx-http-annotations.utils";
import { HttpClient } from "@angular/common/http";
import { HttpClientModule } from "@angular/common/http";

import {CommonModule} from "@angular/common";
// @dynamic
@NgModule({
imports: [HttpClientModule],
imports: [CommonModule, HttpClientModule],
providers: [
{ provide: APP_INITIALIZER, useFactory: onAppInit, multi: true, deps: [HttpClient] }
]
})
export class HttpRestModule {

}

export function onAppInit(http: HttpClient) {
Expand Down
61 changes: 46 additions & 15 deletions src/ngx-http-rest.utils.ts → src/ngx-http-annotations.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,18 @@ export function observe(annotations: any) {
return (...args: any[]) => HttpRestUtils.decorate.apply(this, ['observe', annotations, ...args]);
}
export function path(annotations: any) {
return (...args: any[]) => HttpRestUtils.decorate.apply(this, ['path', annotations, ...args]);
return (...args: any[]) => {
return HttpRestUtils.decorate.apply(this, ['path', annotations, ...args]);
}
}
export function body(annotations: any) {
return (...args: any[]) => HttpRestUtils.decorate.apply(this, ['body', annotations, ...args]);
}

export function response(annotations: any) {
return (...args: any[]) => HttpRestUtils.decorate.apply(this, ['response', annotations, ...args]);
}

export function query(annotations: any) {
return (...args: any[]) => HttpRestUtils.decorate.apply(this, ['query', annotations, ...args]);
}
Expand All @@ -39,13 +46,13 @@ interface ExtraEntityData {
index: number;
}
const RESOURSE_METADATA_ROOT = 'resources_metadata';

// @dynamic
export class HttpRestUtils {

public static http: HttpClient;
public static http: HttpClient = null;

public static decorate(decoratorName: string, annotations: any, ...args: any[]) {
switch (args.length) {
switch (args.length) {
case 1: {
const [target] = args;
HttpRestUtils.constructMetadata.apply(this, [ decoratorName, 'class', annotations, target.prototype ]);
Expand Down Expand Up @@ -80,6 +87,7 @@ export class HttpRestUtils {
* @param entityData Entity extra data
*/
private static constructMetadata(metaName: string, entityType: ResourceMetadataType, value: any, target: any, entityData?: ExtraEntityData) {

target[RESOURSE_METADATA_ROOT] = target[RESOURSE_METADATA_ROOT] || {};
target[RESOURSE_METADATA_ROOT][entityType] = target[RESOURSE_METADATA_ROOT][entityType] || {};

Expand All @@ -102,22 +110,39 @@ export class HttpRestUtils {
}

public static requestMethod(requestMethodName: string): any {
// @dynamic
return (target: any, key: string, descriptor: any) => {
let originalFunction = descriptor.value;
descriptor.value = function (...args: any[]) {
const url = HttpRestUtils.collectUrl(target, key, args);
const body = HttpRestUtils.collectBody(target, key, args);
const search = HttpRestUtils.collectQueryParams(target, key, args);
const headers = HttpRestUtils.collectHeaders(target, key, args);
const producesType = HttpRestUtils.produce(target, key, args);
const observe = HttpRestUtils.getObserve(target, key, args)
const params: httpRequestOptions = {
const observe = HttpRestUtils.getObserve(target, key, args);
const params: any = {
body,
params: search,
headers,
responseType: producesType,
observe
};
return HttpRestUtils.http.request(requestMethodName, url, params);
let request = HttpRestUtils.http.request(requestMethodName, url, params);

const responseIndex = HttpRestUtils.collectResponseIndex(target, key, args);

if (responseIndex >= 0) {
const newArgs = args;
if (args.length > responseIndex) {
newArgs[responseIndex] = request;
} else {
newArgs.splice(responseIndex, 0, request);
}

return originalFunction(...newArgs);
}

return request;
};
};
}
Expand All @@ -135,7 +160,7 @@ export class HttpRestUtils {
&& target[RESOURSE_METADATA_ROOT].methods[methodName]) {
return target[RESOURSE_METADATA_ROOT].methods[methodName].produces;
}
return undefined;
return 'json';
}

private static collectUrl(target: any, methodName: string, args: any[]) {
Expand Down Expand Up @@ -182,12 +207,21 @@ export class HttpRestUtils {
return args[index];
}

private static collectResponseIndex(target: any, methodName: string, args: any[]) {
if (!target[RESOURSE_METADATA_ROOT].params
|| !target[RESOURSE_METADATA_ROOT].params[methodName]
|| !target[RESOURSE_METADATA_ROOT].params[methodName].response) return undefined;

const index = target[RESOURSE_METADATA_ROOT].params[methodName].response.default;
return index;
}

private static collectQueryParams(target: any, methodName: string, args: any[]) {
if (!target[RESOURSE_METADATA_ROOT].params
|| !target[RESOURSE_METADATA_ROOT].params[methodName]
|| !target[RESOURSE_METADATA_ROOT].params[methodName].query) return undefined;

let queryParams = new HttpParams();
let queryParams = {};
const queryParamsObjectIndex = target[RESOURSE_METADATA_ROOT].params[methodName].query.default;
const queryMetadata = target[RESOURSE_METADATA_ROOT].params[methodName].query;
const queryParamsCollection = queryParamsObjectIndex != undefined
Expand All @@ -200,7 +234,7 @@ export class HttpRestUtils {
.forEach(paramName => {
let value = queryParamsCollection[paramName];
if (!Array.isArray(value)) { value = [ value ]; }
value.forEach((curParam: any) => queryParams = queryParams.append(paramName, curParam));
value.forEach((curParam: any) => queryParams [paramName] = curParam);
});
return queryParams;
}
Expand All @@ -212,10 +246,7 @@ export class HttpRestUtils {
: {};
const mergedHeaders = Object.assign({}, classHeaders, methodHeaders);

const httpHeaders = new HttpHeaders();
for (const header in mergedHeaders) {
httpHeaders.append(header, mergedHeaders[header]);
}
return httpHeaders;

return mergedHeaders;
}
}
Loading