{"id":15019395,"url":"https://github.com/dkhrunov/ngx-http-decorators","last_synced_at":"2025-05-02T07:33:15.861Z","repository":{"id":65548006,"uuid":"530356082","full_name":"dkhrunov/ngx-http-decorators","owner":"dkhrunov","description":"A library to simplify working with Http requests by describing these requests in a declarative style using decorators.","archived":false,"fork":false,"pushed_at":"2024-08-17T01:04:50.000Z","size":868,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"development","last_synced_at":"2024-10-29T23:13:20.933Z","etag":null,"topics":["angular","api-client","api-rest","api-wrapper","declarative-programming","decorators","http-client","ngx-http-decorators","reflect-metadata","rest","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/ngx-http-decorators","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dkhrunov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-29T19:03:02.000Z","updated_at":"2024-07-29T17:51:12.000Z","dependencies_parsed_at":"2024-01-12T07:25:42.658Z","dependency_job_id":"653915c8-d989-462c-9652-63d636e9dd7f","html_url":"https://github.com/dkhrunov/ngx-http-decorators","commit_stats":{"total_commits":18,"total_committers":3,"mean_commits":6.0,"dds":0.4444444444444444,"last_synced_commit":"552fb69e2ac3aad4dc96735b880b19832132f827"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkhrunov%2Fngx-http-decorators","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkhrunov%2Fngx-http-decorators/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkhrunov%2Fngx-http-decorators/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkhrunov%2Fngx-http-decorators/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dkhrunov","download_url":"https://codeload.github.com/dkhrunov/ngx-http-decorators/tar.gz/refs/heads/development","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224305847,"owners_count":17289446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","api-client","api-rest","api-wrapper","declarative-programming","decorators","http-client","ngx-http-decorators","reflect-metadata","rest","typescript"],"created_at":"2024-09-24T19:53:25.626Z","updated_at":"2024-11-12T16:04:55.023Z","avatar_url":"https://github.com/dkhrunov.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NgxHttpDecorators\n\nA library to simplify working with Http requests by describing these requests in a declarative style using decorators.\n\n## Contents\n\n- [Settings](#settings)\n- [Creating Api service](#creating-api-service)\n  - [GET request](#get-request)\n  - [GET request with path parameters](#get-request-with-path-parameters)\n  - [Request with Body](#request-with-body)\n  - [Request with Query Params](#request-with-query-params)\n  - [Request with Headers](#request-with-headers)\n  - [Reqeust with HttpContext](#request-with-httpcontext)\n- [Decorators](#decorators)\n  - [@HttpController()](#httpcontroller)\n  - [@Get()](#get)\n  - [@Post()](#post)\n  - [@Put()](#put)\n  - [@Patch()](#patch)\n  - [@Delete()](#delete)\n  - [request()](#request)\n  - [@Param() and @Params()](#param-and-params)\n  - [@Query() and @Queries()](#query-and-queries)\n  - [@Body()](#body)\n  - [@Header()](#header)\n  - [@Context()](#context)\n  \n## Settings\n\nTo get started with __NgxHttpDecorators__, you need to import `NgxHttpDecoratorsModule` into your application's **app/core** module.\n\nIf most of your requests use the same host (base server url), then it can be specified using the `NGX_HTTP_DECORATORS_HOST_URL` InjectionToken as in the example below. \n\n\u003e It is not necessary to specify this, and further it will be shown how it will be possible to override this property in the Api service.\n\n```typescript\n@NgModule({\n  imports: [NgxHttpDecoratorsModule],\n  providers: [\n    {\n      provide: NGX_HTTP_DECORATORS_HOST_URL,\n      useValue: 'https://test-api.com',\n    },\n  ],\n})\nexport class AppModule {}\n```\n\n\n## Creating Api service\n\nAn api service is a regular service in which methods will make requests to specific endpoints.\n\nIt is good practice to separate these services into features. For example, requests for working with users are described in UserService, and requests for working with posts will be described in a separate PostService.\n\nLet's create a service for working with posts:\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {}\n```\n\nAs you can see, after the standard `@Injectable()` decorator, we specified the `@HttpController()` decorator, the parameter in the form of the string `'/api/posts'` defines the prefix for all requests in this service. You can also pass an object with settings to the `@HttpController({ ... })` decorator.\n\n\u003e The `@HttpController()` decorator is not required to be added to every API service, add this decorator if you really need its functionality.\n\n### GET request\n\nFurther in the service, you can describe the requests that this service can perform.\n\nFirst, let's create a GET request `'/api/posts'` to get all the posts:\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n\n  @Get()\n  public getAll(): Observable\u003cPost[]\u003e {\n    return request(this.getAll);\n  }\n}\n```\n\n\u003e Note that the function returns a `request(this.getAll)` function with a reference to this method, it is necessary for the decorated method to return the `Observable` of the request, as we usually did with HttpClient.\n\u003e\n\u003e **The given `request(this.decorated Method)` construct is always returned from the declared method.**\n\u003e\n\u003e because function `request(...)` returns `Observable` we can pipe any RxJs operator. For example, map the value into an array of post Ids:\n\u003e\n\u003e ```typescript\n\u003e @Get()\n\u003e public getAll(): Observable\u003cnumber[]\u003e {\n\u003e   return request(this.getAll).pipe(map(x =\u003e x.map(p =\u003e p.id)));\n\u003e }\n\u003e ```\n\n### GET request with path parameters\n\nNow let's try to create a GET request `'/api/posts/:postId'` to get a post by Id:\n\n\u003e In order for the `id` argument of the `get` method to be inserted into the url, in the url itself you must specify a unique path parameter using the `:param_name` mask, and in the method arguments add and mark with the decorator `@Param('param_name')` parameter, then the value of this parameter will be substituted in the url each time this method is called.\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n\n  @Get()\n  public getAll(): Observable\u003cPost[]\u003e {\n    return request(this.getAll);\n  }\n\n  @Get('/:postId')\n  public get(@Param('postId') id: number): Observable\u003cPost\u003e {\n    return request(this.get);\n  }\n}\n```\n\nIf you call the get method, for example, with the value 11 `this._postService.get(11)`, then we will send a request to such a url - `'/api/posts/11'`;\n\n### Request with Body\n\nNow let's try to make a POST request to `'/api/posts'` to create a new post in the system:\n\n\u003e In order to specify a request Body, you need to decorate the method argument with the `@Body()` decorator.\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n\n  @Post()\n  public create(@Body() data: CreatePostDto): Observable\u003cPost\u003e {\n    return request(this.create);\n  }\n}\n```\n\n### Request with Query Params\n\nLet's create a query in which we want to pass data to the Query Params of the request. \n\nCreate a query filtering posts by certain criteria, which will be passed to the Query Params of the query:\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n  [...]\n\n  @Get()\n  public getWithFilter(\n    @Query('published') published?: boolean,\n    @Query('author') author?: string,\n    @Query('publishDate') publishDate?: string,\n  ): Observable\u003cPost[]\u003e {\n    return request(this.getWithFilter);\n  }\n}\n```\n\nIf there are many parameters, then you can combine them all into an object and pass the Query Params object to the method:\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n  [...]\n\n  @Get()\n  public getWithFilter(\n    @Queries() params?: { published?: boolean, author?: string, publishDate?: string },\n  ): Observable\u003cPost[]\u003e {\n    return request(this.getWithFilter);\n  }\n}\n```\n\nIf you call the `getWithFilter()` method, for example, with the object `{ published: true, author: 'Dostoevsky' }` `this._postService.get({ published: true, author: 'Dostoevsky' })`, then we will send request for such url - `'/api/posts?published=true\u0026author=Dostoevsky'`.\n\n### Request with Headers\n\nNow let's try to specify a header for the request:\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n  [...]\n\n  @Post()\n  @Header('X-Custom', 'value')\n  public create(@Body() data: CreatePostDto): Observable\u003cPost\u003e {\n    return request(this.create);\n  }\n}\n```\n\nYou can specify multiple headers:\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n  [...]\n\n  @Post()\n  @Header('X-Custom-1', 'value1')\n  @Header('X-Custom-2', 'value2')\n  public create(@Body() data: CreatePostDto): Observable\u003cPost\u003e {\n    return request(this.create);\n  }\n}\n```\n\nIf an entire group of requests in a service requires a specific header, then this can be solved by specifying the `@Header()` decorator on the class, then all methods in this class will have this header:\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\n@Header('X-Posts-Header', 'all')\nexport class PostService {\n  // the request will contain only one header - 'X-Posts-Header'\n  @Get()\n  public getAll(): Observable\u003cPost[]\u003e {\n    return request(this.getAll);\n  }\n\n  // the request will contain two headers: 'X-Post-Header' and 'X-Custom-2'\n  @Get('/:postId')\n  @Header('X-Custom-2', 'value2')\n  public get(@Param('postId') id: number): Observable\u003cPost\u003e {\n    return request(this.get);\n  }\n}\n```\n\n### Reqeust with HttpContext\n\n\n`HttpContext` is used to store additional metadata that can be accessed from HTTP interceptors.\n\n\u003e [More about HttpContext](https://angular.io/api/common/http/HttpContext).\n\nAdd `HttpContext` to the request:\n\n```typescript\nconst IS_PUBLIC_API = new HttpContextToken\u003cboolean\u003e(() =\u003e false);\n\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n  @Get()\n  @Context(IS_PUBLIC_API, true)\n  public getAll(): Observable\u003cPost[]\u003e {\n    return request(this.getAll);\n  }\n}\n```\n\nAs with the `@Header()` decorator, we can add multiple HttpContexts per request:\n\n```typescript\nconst IS_PUBLIC_API = new HttpContextToken\u003cboolean\u003e(() =\u003e false);\nconst IS_CACHE_ENABLED = new HttpContextToken\u003cboolean\u003e(() =\u003e false);\n\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n  @Get()\n  @Context(IS_PUBLIC_API, true)\n  @Context(IS_CACHE_ENABLED, true)\n  public getAll(): Observable\u003cPost[]\u003e {\n    return request(this.getAll);\n  }\n}\n```\n\n## Decorators\n\nDecorators documentation.\n\n### @HttpController()\n\nThe class decorator is used to set some properties for all requests in a given service.\n\nThis decorator is optional to add to each api service, add this decorator if you really need its functionality.\n\nThe decorator has two variations (overloads):\n\n1. A string is passed as a parameter to the decorator, which specifies the prefix for all requests in this class;\n\n   ```typescript\n   @Injectable({\n     providedIn: 'root',\n   })\n   @HttpController('/api/posts')\n   export class PostService {}\n   ```\n\n2. As a parameter, an object is passed to the decorator, in which you can specify `host` - the server where requests will be sent, and `pathPrefix` - a prefix string for all requests. Both parameters are optional;\n\n   ```typescript\n   @Injectable({\n     providedIn: 'root',\n   })\n   @HttpController({\n     host: 'https://server.com',\n     pathPrefix: '/api/posts',\n   })\n   export class PostService {}\n   ```\n\n### @Request()\n\nMethod decorator. Creates an HTTP request. The third argument is the request options optional `options: DecoratedHttpRequestOptions`.\n\n```typescript\n@Request(HttpMethod.Get, '/api/posts', options)\npublic getPosts(): Observable\u003cPost[]\u003e {\n  return request(this.getPosts);\n}\n```\n\n### @Get()\n\nMethod decorator. Creates a GET request. The second argument is the request options optional `options: DecoratedHttpRequestOptions`.\n\n```typescript\n@Get('/api/posts', options)\npublic getPosts(): Observable\u003cPost[]\u003e {\n  return request(this.getPosts);\n}\n```\n\n### @Post()\n\nMethod decorator. Creates a POST request. The second argument is the request options optional `options: DecoratedHttpRequestOptions`.\n\n```typescript\n@Post('/api/posts', options)\npublic create(): Observable\u003cPost\u003e {\n  return request(this.create);\n}\n```\n\n### @Put()\n\nMethod decorator. Creates a PUT request. The second argument is the request options optional `options: DecoratedHttpRequestOptions`.\n\n```typescript\n@Put('/api/posts', options)\npublic create(): Observable\u003cPost\u003e {\n  return request(this.create);\n}\n```\n\n### @Patch()\n\nMethod decorator. Creates a PATCH request. The second argument is the request options optional `options: DecoratedHttpRequestOptions`.\n\n```typescript\n@Patch('/api/posts', options)\npublic create(): Observable\u003cPost\u003e {\n  return request(this.create);\n}\n```\n\n### @Delete()\n\nMethod decorator. Creates a DELETE request. The second argument is the request options optional `options: DecoratedHttpRequestOptions`.\n\n```typescript\n@Delete('/api/posts/:id', options)\npublic delete(@Param('id') id: number): Observable\u003cvoid\u003e {\n  return request(this.delete);\n}\n```\n\n### request()\n\nThe method decorated with the `@Request()`, `@Get()`, `@Post()`, `@Put`, `@Patch` and `@Delete` decorators must always return `return request(this.decoratedMethod )` so that the decorated method returns the `Observable` of the request.\n\n```typescript\n@Get()\npublic getPosts(): Observable\u003cPost[]\u003e {\n  return request(this.getPosts);\n}\n```\n\n### @Param() и @Params()\n\nParameter decorator. Specifies the path parameter for the request, replacing the wildcard in the path with the value of the decorated argument.\n\n- @Param('name') - the value is the key for the parameter, and the value is taken from the decorated argument.\n\n  ```typescript\n  @Injectable({\n    providedIn: 'root',\n  })\n  @HttpController('/api/posts')\n  export class PostService {\n    @Get('/:postId')\n    public get(@Param('postId') id: number): Observable\u003cPost\u003e {\n      return request(this.get);\n    }\n  }\n  ```\n\n- @Params() - the object from the value of the decorative argument maps into the path parameters.\n\n  ```typescript\n  @Injectable({\n    providedIn: 'root',\n  })\n  @HttpController('/api/user')\n  export class PostService {\n    @Get('/:userId/posts/:postId')\n    public get(\n      @Params() data: { userId: number; postId: number }\n    ): Observable\u003cPost\u003e {\n      return request(this.get);\n    }\n  }\n  ```\n\n### @Query() и @Queries()\n\nParameter decorator. Specifies a query parameter, where the value of the decorated argument is the value of the Query Params.\n\n- @Query('name') - the value is the key for the parameter, and the value is taken from the decorated argument.\n\n  ```typescript\n  @Injectable({\n    providedIn: 'root',\n  })\n  @HttpController('/api/posts')\n  export class PostService {\n    [...]\n\n    @Get()\n    public getWithFilter(\n      @Query('published') published?: boolean,\n      @Query('author') author?: string,\n      @Query('publishDate') publishDate?: string,\n    ): Observable\u003cPost[]\u003e {\n      return request(this.getWithFilter);\n    }\n  }\n  ```\n\n- @Queries() - the object from the value of the decorative argument is mapped to Query Params.\n\n  ```typescript\n  @Injectable({\n    providedIn: 'root',\n  })\n  @HttpController('/api/posts')\n  export class PostService {\n    [...]\n\n    @Get()\n    public getWithFilter(\n      @Queries() params?: { published?: boolean, author?: string, publishDate?: string },\n    ): Observable\u003cPost[]\u003e {\n      return request(this.getWithFilter);\n    }\n  }\n  ```\n\n### @Body()\n\nParameter decorator. Specifies the request body with the value of the decorated parameter.\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n  @Post()\n  public create(@Body() data: CreatePostDto): Observable\u003cPost\u003e {\n    return request(this.create);\n  }\n}\n```\n\n### @Header()\n\nMethod or class decorator. Sets the request header. When applied to a class, this header will be sent with all requests in that class.\n\n```typescript\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\n@Header('X-Posts-Header', 'all')\nexport class PostService {\n  // the request will contain only one header - 'X-Posts-Header'\n  @Get()\n  public getAll(): Observable\u003cPost[]\u003e {\n    return request(this.getAll);\n  }\n\n  // the request will contain two headers: 'X-Post-Header' and 'X-Custom-2'\n  @Get('/:postId')\n  @Header('X-Custom-2', 'value2')\n  public get(@Param('postId') id: number): Observable\u003cPost\u003e {\n    return request(this.get);\n  }\n}\n```\n\n### @Context()\n\nMethod decorator. Specifies the `HttpContext` for the request. `HttpContext` is used to store additional metadata that can be accessed from HTTP Interceptors.\n\n\u003e [More about HttpContext](https://angular.io/api/common/http/HttpContext).\n\n\n```typescript\nconst IS_PUBLIC_API = new HttpContextToken\u003cboolean\u003e(() =\u003e false);\nconst IS_CACHE_ENABLED = new HttpContextToken\u003cboolean\u003e(() =\u003e false);\n\n@Injectable({\n  providedIn: 'root',\n})\n@HttpController('/api/posts')\nexport class PostService {\n  @Get()\n  @Context(IS_PUBLIC_API, true)\n  @Context(IS_CACHE_ENABLED, true)\n  public getAll(): Observable\u003cPost[]\u003e {\n    return request(this.getAll);\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkhrunov%2Fngx-http-decorators","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdkhrunov%2Fngx-http-decorators","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkhrunov%2Fngx-http-decorators/lists"}