{"id":3873,"date":"2017-08-08T07:00:18","date_gmt":"2017-08-08T14:00:18","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=3873"},"modified":"2025-06-13T20:15:13","modified_gmt":"2025-06-14T03:15:13","slug":"creating-front-end-user-profile-store-angular-typescript","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/creating-front-end-user-profile-store-angular-typescript\/","title":{"rendered":"Use TypeScript e Angular como front-end para seu armazenamento de perfis de usu\u00e1rio"},"content":{"rendered":"<p>Recentemente, escrevi um tutorial intitulado,\u00a0<a href=\"https:\/\/www.couchbase.com\/blog\/pt\/creating-user-profile-store-with-node-js-nosql-database\/\" target=\"_blank\" rel=\"noopener noreferrer\">Cria\u00e7\u00e3o de um armazenamento de perfil de usu\u00e1rio com Node.js e um banco de dados NoSQL<\/a>pois esse \u00e9 um assunto e um caso de uso muito popular quando se trata de bancos de dados NoSQL. Nesse tutorial, criamos uma API <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/build-a-rest-api-with-node-js-express-and-couchbase\/\">usando Node.js<\/a> e <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase<\/a> para armazenar usu\u00e1rios, informa\u00e7\u00f5es associadas a determinados usu\u00e1rios e sess\u00f5es expiradas. No entanto, ele era estritamente relacionado ao back-end, sem interface com o usu\u00e1rio.<\/p>\n<p>Quer\u00edamos usar a API de armazenamento de perfil de usu\u00e1rio e entender <span style=\"font-weight: 400\">como criar, usando TypeScript e Angular, <\/span>uma p\u00e1gina de perfil que se comunica com cada um dos pontos de extremidade da API.<\/p>\n<p><strong>Este tutorial foi atualizado em 7 de janeiro de 2021 por <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/author\/eric-bishard\/\">Eric Bishard<\/a> para trabalhar com o Angular 11!<\/strong><\/p>\n<p><!--more--><\/p>\n<p>Antes de continuar, presumimos que voc\u00ea tenha seguido o <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/creating-user-profile-store-with-node-js-nosql-database\/\" target=\"_blank\" rel=\"noopener noreferrer\">tutorial anterior<\/a>. Tamb\u00e9m vamos supor que voc\u00ea tenha o <a href=\"https:\/\/cli.angular.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">CLI angular<\/a> instalado.<\/p>\n<h2>Criar um projeto Angular com os componentes necess\u00e1rios<\/h2>\n<p>O front-end do cliente ser\u00e1 rudimentar, mas o criaremos do zero. Do ponto de vista do design, ele n\u00e3o ter\u00e1 uma \u00f3tima apar\u00eancia, pois este tutorial trata da funcionalidade e do trabalho com a nossa API. Voc\u00ea \u00e9 quem decide se quer deix\u00e1-lo bonito e oferecer uma experi\u00eancia do usu\u00e1rio melhor.<\/p>\n<p>Na CLI do Angular, execute o seguinte comando:<\/p>\n<pre class=\"lang:default decode:true\">ng new couchbase-angular-blog-app<\/pre>\n<p>O comando acima criar\u00e1 um novo projeto no caminho da CLI. Com o projeto criado, precisaremos criar um componente para cada uma das p\u00e1ginas esperadas do aplicativo.<\/p>\n<p>Execute o seguinte com a CLI do Angular:<\/p>\n<pre class=\"lang:default decode:true\">ng g component login\r\nng g component register\r\nng g component blogs\r\nng g component blog<\/pre>\n<p>Ser\u00e3o criados quatro componentes de perfil de usu\u00e1rio do Angular, cada um com arquivos TypeScript e HTML apropriados. Antes de come\u00e7armos a adicionar l\u00f3gica a eles, precisamos uni-los para fins de navega\u00e7\u00e3o usando o modelo de perfil de usu\u00e1rio do Angular abaixo.<\/p>\n<p>Abra o arquivo\u00a0<strong>src\/app\/app.module.ts<\/strong> e inclua o seguinte:<\/p>\n<pre class=\"lang:default decode:true\">import { BrowserModule } from '@angular\/platform-browser';\r\nimport { NgModule } from '@angular\/core';\r\nimport { FormsModule } from '@angular\/forms';\r\nimport { HttpClientModule } from '@angular\/common\/http';\r\n\r\nimport { AppComponent } from '.\/app.component';\r\nimport { LoginComponent } from '.\/login\/login.component';\r\nimport { RegisterComponent } from '.\/register\/register.component';\r\nimport { BlogsComponent } from '.\/blogs\/blogs.component';\r\nimport { BlogComponent } from '.\/blog\/blog.component';\r\nimport { RouterModule } from '@angular\/router';\r\n\r\nlet routes = [\r\n  { path: '', redirectTo: '\/login', pathMatch: 'full' }, \r\n  { path: 'login', component: LoginComponent }, \r\n  { path: 'register', component: RegisterComponent }, \r\n  { path: 'blogs', component: BlogsComponent }, \r\n  { path: 'blog', component: BlogComponent }\r\n];\r\n\r\n@NgModule({\r\n  declarations: [\r\n    AppComponent,\r\n    LoginComponent,\r\n    RegisterComponent,\r\n    BlogsComponent,\r\n    BlogComponent\r\n  ],\r\n  imports: [\r\n    BrowserModule,\r\n    FormsModule,\r\n    HttpClientModule,\r\n    RouterModule, \r\n    RouterModule.forRoot(routes)\r\n  ],\r\n  providers: [],\r\n  bootstrap: [AppComponent]\r\n})\r\nexport class AppModule { }\r\n<\/pre>\n<p>O c\u00f3digo acima foi criado pela CLI do Angular, no entanto, adicionamos algumas importa\u00e7\u00f5es de m\u00f3dulos principais e personalizados e os importamos junto com o <code>rotas<\/code> no <code>@NgModule<\/code> bloco.<\/p>\n<p>Para ativar nossa navega\u00e7\u00e3o, precisaremos atualizar um arquivo. Abra o arquivo\u00a0<strong>src\/app\/app.component.html<\/strong> e substitua todo o conte\u00fado pelo seguinte:<\/p>\n<pre class=\"lang:default decode:true\">&lt;router-outlet&gt;&lt;\/router-outlet&gt;<\/pre>\n<p>Neste ponto, o projeto de perfil de usu\u00e1rio tem uma configura\u00e7\u00e3o b\u00e1sica com o Angular.<\/p>\n<p>Vamos dar uma olhada no tratamento da cria\u00e7\u00e3o de perfis de usu\u00e1rio e no login com as informa\u00e7\u00f5es da conta.<\/p>\n<h2>Manipula\u00e7\u00e3o de login e registro<\/h2>\n<p>A primeira tela que o usu\u00e1rio ver\u00e1 \u00e9 a tela de login. O objetivo aqui \u00e9 coletar um nome de usu\u00e1rio e uma senha, envi\u00e1-los \u00e0 API, obter um ID de sess\u00e3o como resposta e us\u00e1-lo em todas as p\u00e1ginas futuras do aplicativo.<\/p>\n<p>Abra o arquivo\u00a0<strong>src\/app\/login\/login.component.ts<\/strong> e inclua o seguinte c\u00f3digo TypeScript:<\/p>\n<pre class=\"lang:default decode:true\">import { Component, OnInit } from '@angular\/core';\r\nimport { HttpClient, HttpHeaders } from '@angular\/common\/http';\r\nimport { Router } from '@angular\/router'; \r\n\r\n@Component({\r\n  selector: 'app-login',\r\n  templateUrl: '.\/login.component.html',\r\n  styleUrls: ['.\/login.component.css']\r\n})\r\n\r\nexport class LoginComponent implements OnInit {\r\n\r\n  public input: any;\r\n\r\n  constructor(private http: HttpClient, private router: Router) {\r\n    this.input = {\r\n      'email': '',\r\n      'password': ''\r\n    };\r\n  }\r\n\r\n  ngOnInit(): void { }\r\n\r\n  public login() {\r\n    if (this.input.email &amp;&amp; this.input.password) {\r\n      let headers = new HttpHeaders({ 'content-type': 'application\/json' });\r\n      this.http.post('https:\/\/localhost:3000\/login', JSON.stringify(this.input), { headers: headers })\r\n        .subscribe(result =&gt; \r\n          this.router.navigate(['\/blogs'], { 'queryParams': result })\r\n        );\r\n    }\r\n  }\r\n\r\n}<\/pre>\n<p>H\u00e1 algumas coisas importantes acontecendo no c\u00f3digo acima, portanto, vamos detalh\u00e1-lo.<\/p>\n<p>Nossa inten\u00e7\u00e3o \u00e9 vincular um objeto a um formul\u00e1rio na marca\u00e7\u00e3o HTML. Esse objeto ser\u00e1 o <code>entrada<\/code> vari\u00e1vel. Na <code>construtor<\/code> definimos cada propriedade poss\u00edvel como um valor vazio que ser\u00e1 refletido na interface do usu\u00e1rio.<\/p>\n<p>Quando o usu\u00e1rio decide fazer login, as informa\u00e7\u00f5es de cabe\u00e7alho apropriadas s\u00e3o definidas para a solicita\u00e7\u00e3o e o objeto \u00e9 enviado ao servidor. Se for bem-sucedida, a resposta ser\u00e1 um objeto com o ID da sess\u00e3o. Vamos pass\u00e1-lo para a pr\u00f3xima p\u00e1gina como um par\u00e2metro de consulta.<\/p>\n<p>A marca\u00e7\u00e3o HTML que combina com esse TypeScript \u00e9 encontrada no arquivo\u00a0<strong>src\/app\/login\/login.component.html<\/strong> e ele se parece com o seguinte:<\/p>\n<h2 style=\"margin: 0\">Entrar<\/h2>\n<p>&nbsp;<\/p>\n<p><label for=\"email\">E-mail:<\/label><\/p>\n<p><label for=\"password\">Senha:<\/label><\/p>\n<p><button type=\"button\">Login<\/button><\/p>\n<p><a>Registro<\/a><\/p>\n<pre class=\"lang:default decode:true\"><\/pre>\n<p>Uma observa\u00e7\u00e3o que devo mencionar aqui \u00e9 que, se voc\u00ea digitar a senha errada, n\u00e3o criamos nenhuma forma de informar ao usu\u00e1rio que o nome de usu\u00e1rio ou a senha usada n\u00e3o estava correta.<\/p>\n<p>O que \u00e9 importante aqui \u00e9 o uso do <code>[(ngModel)]<\/code> que s\u00e3o usados para vincula\u00e7\u00e3o de dados. Tamb\u00e9m oferecemos navega\u00e7\u00e3o para a p\u00e1gina de registro por meio do atributo\u00a0<code>[routerLink]<\/code> atributo.<\/p>\n<p>Ent\u00e3o, como \u00e9 o componente de registro?<\/p>\n<p>Abra o arquivo\u00a0<strong>src\/app\/register\/register.component.ts<\/strong> e inclua o seguinte c\u00f3digo TypeScript:<\/p>\n<pre class=\"lang:default decode:true\">import { Component, OnInit } from '@angular\/core';\r\nimport { HttpClient, HttpHeaders } from '@angular\/common\/http';\r\nimport { Router } from '@angular\/router';\r\n\r\n@Component({\r\n  selector: 'app-register',\r\n  templateUrl: '.\/register.component.html',\r\n  styleUrls: ['.\/register.component.css']\r\n})\r\n\r\nexport class RegisterComponent implements OnInit {\r\n\r\n  public input: any;\r\n\r\n  public constructor(private http: HttpClient, private router: Router) {\r\n    this.input = {\r\n      'firstname': '',\r\n      'lastname': '',\r\n      'email': '',\r\n      'password': ''\r\n    };\r\n  }\r\n\r\n  ngOnInit(): void { }\r\n\r\n  public register() {\r\n    if (this.input.email &amp;&amp; this.input.password) {\r\n      let headers = new HttpHeaders({ 'content-type': 'application\/json' });\r\n      this.http.post('https:\/\/localhost:3000\/account', JSON.stringify(this.input), { headers: headers })\r\n        .subscribe(() =&gt;\r\n          this.router.navigate(['\/login'])\r\n        );\r\n    }\r\n  }\r\n\r\n}<\/pre>\n<p>Voc\u00ea perceber\u00e1 que o c\u00f3digo de registro \u00e9 semelhante ao c\u00f3digo de login. Estamos apenas coletando dados de formul\u00e1rio e enviando-os para um endpoint de API diferente.<\/p>\n<p>O HTML correspondente encontrado no arquivo\u00a0<strong>src\/app\/register\/register.component.html<\/strong> tem a seguinte apar\u00eancia:<\/p>\n<h2 style=\"margin: 0\">Registro<\/h2>\n<p>&nbsp;<\/p>\n<p><label for=\"firstname\">Primeiro nome:<\/label><\/p>\n<p><label for=\"lastname\">Sobrenome:<\/label><\/p>\n<p><label for=\"email\">E-mail:<\/label><\/p>\n<p><label for=\"password\">Senha:<\/label><\/p>\n<p><button type=\"button\">Registro<\/button><\/p>\n<p><a>Login<\/a><\/p>\n<pre class=\"lang:default decode:true\"><\/pre>\n<p>O HTML cont\u00e9m elementos de formul\u00e1rio vinculados ao <code>[(ngModel)]<\/code> bem como um link para a p\u00e1gina de login.<\/p>\n<p>Lembre-se de que, depois de fazermos o login, estamos passando a sess\u00e3o para as p\u00e1ginas espec\u00edficas do usu\u00e1rio. Isso nos permitir\u00e1 obter as informa\u00e7\u00f5es do usu\u00e1rio em nosso armazenamento de perfis.<\/p>\n<h2>Cria\u00e7\u00e3o e exibi\u00e7\u00e3o de artigos de blog para um usu\u00e1rio espec\u00edfico no Profile Store<\/h2>\n<p>Depois de fazer login, o usu\u00e1rio \u00e9 levado a uma p\u00e1gina em que pode visualizar uma lista de artigos de blog que escreveu. Lembre-se de que nosso backend est\u00e1 conectando documentos NoSQL por meio de um ID de perfil que estamos definindo.<\/p>\n<p>Para visualizar os artigos do blog, o ID da sess\u00e3o passado da p\u00e1gina anterior precisa ser definido como um cabe\u00e7alho em uma solicita\u00e7\u00e3o. O resultado da solicita\u00e7\u00e3o pode ser imediatamente renderizado na tela.<\/p>\n<p>Abra o arquivo\u00a0<strong>src\/app\/blogs\/blogs.component.ts<\/strong> e inclua o seguinte c\u00f3digo TypeScript:<\/p>\n<pre class=\"lang:default decode:true\">import { Component, OnInit } from '@angular\/core';\r\nimport { HttpClient, HttpHeaders } from '@angular\/common\/http';\r\nimport { Router, ActivatedRoute } from '@angular\/router';\r\n\r\n@Component({\r\n  selector: 'app-blogs',\r\n  templateUrl: '.\/blogs.component.html',\r\n  styleUrls: ['.\/blogs.component.css']\r\n})\r\n\r\nexport class BlogsComponent implements OnInit {\r\n\r\n  private sid: string;\r\n  public entries: any; \r\n\r\n  public constructor(\r\n    private http: HttpClient, \r\n    private router: Router, \r\n    private route: ActivatedRoute\r\n  ) {\r\n    this.entries = [];\r\n  }\r\n\r\n  public ngOnInit() {\r\n    this.route.queryParams.subscribe(params =&gt; {\r\n      this.sid = params['sid'];\r\n      let headers = new HttpHeaders({ 'authorization': 'Bearer ' + params['sid'] });\r\n      this.http.get('https:\/\/localhost:3000\/blogs', { headers: headers })\r\n        .subscribe(result =&gt; {\r\n          this.entries = result;\r\n          console.log(result)\r\n        });\r\n    });\r\n  }\r\n\r\n  public create() {\r\n    this.router.navigate(['\/blog'], { 'queryParams': { 'sid': this.sid } });\r\n  }\r\n\r\n}<\/pre>\n<p>Esse arquivo segue uma estrat\u00e9gia semelhante \u00e0 forma como lidamos com o login e o registro.<\/p>\n<p>Em termos de vari\u00e1veis, criamos uma vari\u00e1vel privada chamada <code>lado<\/code> que manter\u00e1 a sess\u00e3o passada da p\u00e1gina anterior. O <code>entradas<\/code> ser\u00e1 uma matriz de entradas de blog para um indiv\u00edduo retornado do endpoint da API.<\/p>\n<p>Quando a p\u00e1gina \u00e9 carregada, devemos exibir as entradas do blog. Nunca \u00e9 uma boa ideia carregar ou solicitar dados de dentro do <code>construtor<\/code> portanto, em vez disso, usamos o m\u00e9todo <code>ngOnInit<\/code> m\u00e9todo.<\/p>\n<pre class=\"lang:default decode:true\">public ngOnInit() {\r\n  this.route.queryParams.subscribe(params =&gt; {\r\n    this.sid = params['sid'];\r\n    let headers = new HttpHeaders({ 'authorization': 'Bearer ' + params['sid'] });\r\n    this.http.get('https:\/\/localhost:3000\/blogs', { headers: headers })\r\n      .subscribe(result =&gt; {\r\n        this.entries = result;\r\n        console.log(result)\r\n      });\r\n  });\r\n}<\/pre>\n<p>No <code>ngOnInit<\/code> podemos pegar os par\u00e2metros passados e construir um cabe\u00e7alho de autoriza\u00e7\u00e3o. Em seguida, fazemos uma solicita\u00e7\u00e3o ao nosso endpoint que cont\u00e9m o cabe\u00e7alho.<\/p>\n<p>Para criar uma nova entrada de blog, podemos passar o par\u00e2metro <code>lado<\/code> para a pr\u00f3xima rota:<\/p>\n<pre class=\"lang:default decode:true\">public create() {\r\n  this.router.navigate(['\/blog'], { 'queryParams': { 'sid': this.sid } });\r\n}<\/pre>\n<p>Isso \u00e9 exatamente como o que vimos na tela de login.<\/p>\n<p>A marca\u00e7\u00e3o HTML que alimenta a interface do usu\u00e1rio n\u00e3o ser\u00e1 mais complexa do que a l\u00f3gica TypeScript que a alimenta. O HTML pode ser visto na se\u00e7\u00e3o\u00a0<strong>src\/app\/blogs\/blogs.component.html<\/strong> assim:<\/p>\n<h2>Blogs que voc\u00ea escreveu<\/h2>\n<p>&nbsp;<\/p>\n<p><button type=\"button\">Novo<\/button> | <button>Sair<\/button><\/p>\n<p>&nbsp;<\/p>\n<h2>{{ entry.blog.title }}<\/h2>\n<p>&nbsp;<\/p>\n<p>{{ entry.blog.content }}<\/p>\n<p>&nbsp;<\/p>\n<p>A cria\u00e7\u00e3o de uma entrada de blog ter\u00e1 uma l\u00f3gica semelhante \u00e0 que j\u00e1 vimos. Abra a se\u00e7\u00e3o\u00a0<strong>src\/app\/blog\/blog.component.ts<\/strong> e inclua o seguinte c\u00f3digo TypeScript:<\/p>\n<pre class=\"lang:default decode:true\">import { Component, OnInit } from '@angular\/core';\r\nimport { HttpClient, HttpHeaders } from '@angular\/common\/http';\r\nimport { ActivatedRoute } from '@angular\/router';\r\nimport { Location } from '@angular\/common';\r\n\r\n@Component({\r\n  selector: 'app-blog',\r\n  templateUrl: '.\/blog.component.html',\r\n  styleUrls: ['.\/blog.component.css']\r\n})\r\n\r\nexport class BlogComponent implements OnInit {\r\n\r\n  private sid: string;\r\n  public input: any;\r\n\r\n  public constructor(private http: HttpClient, private route: ActivatedRoute, private location: Location) {\r\n    this.input = {\r\n      'title': '',\r\n      'content': ''\r\n    };\r\n  }\r\n\r\n  public ngOnInit() {\r\n    this.route.queryParams.subscribe(params =&gt; {\r\n      this.sid = params['sid'];\r\n    });\r\n  }\r\n\r\n  public save() {\r\n    if (this.input.title &amp;&amp; this.input.content) {\r\n      let headers = new HttpHeaders({\r\n        'content-type': 'application\/json',\r\n        'authorization': 'Bearer ' + this.sid\r\n      });\r\n      this.http.post('https:\/\/localhost:3000\/blog', JSON.stringify(this.input), { headers: headers })\r\n        .subscribe(() =&gt;\r\n          this.location.back()\r\n        );\r\n    }\r\n  }\r\n\r\n}<\/pre>\n<p>No c\u00f3digo acima, estamos inicializando os dados do formul\u00e1rio e recuperando o <code>lado<\/code> que foi passado da p\u00e1gina anterior.<\/p>\n<p>Quando tentamos salvar a entrada, constru\u00edmos um cabe\u00e7alho apropriado que cont\u00e9m o ID da sess\u00e3o e o enviamos para a API com os dados do formul\u00e1rio. Uma vez conclu\u00eddo, podemos navegar para tr\u00e1s na pilha.<\/p>\n<p>O HTML para a interface do usu\u00e1rio dessa p\u00e1gina est\u00e1 no arquivo\u00a0<strong>src\/app\/blog\/blog.component.html<\/strong> assim:<\/p>\n<h2>Nova entrada no blog<\/h2>\n<p>&nbsp;<\/p>\n<p><label for=\"title\">T\u00edtulo<\/label><\/p>\n<p><label for=\"content\">Conte\u00fado<\/label><br \/>\n<textarea style=\"width: 300px;height: 100px\" name=\"content\"><\/textarea><br \/>\n<button type=\"button\">Salvar<\/button><\/p>\n<h2>Manter a consist\u00eancia em mente<\/h2>\n<p>Por padr\u00e3o, o Couchbase tentar\u00e1 ser r\u00e1pido, o que significa que ele pode retornar dados mais rapidamente do que a atualiza\u00e7\u00e3o dos \u00edndices. Quando isso acontece, voc\u00ea pode ter dados rec\u00e9m-criados ausentes em seus resultados.<\/p>\n<p>Expliquei como corrigir isso em um <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/defining-scan-consistency-node-js-couchbase-application\/\" target=\"_blank\" rel=\"noopener noreferrer\">tutorial anterior<\/a>mas uma r\u00e1pida recapitula\u00e7\u00e3o est\u00e1 abaixo.<\/p>\n<pre class=\"lang:default decode:true\">const query = `SELECT * FROM \\`blog\\` WHERE type = 'blog' AND pid = $PID;`\r\nconst options = { \r\n  scanConsistency: couchbase.QueryScanConsistency.RequestPlus,\r\n  parameters: { PID: request.pid }\r\n}\r\nawait cluster.query(query, options)\r\n  .then((result) =&gt; {\r\n    console.log(result.rows)\r\n    response.send(result.rows)\r\n  })\r\n  .catch((e) =&gt; response.status(500).send(e))<\/pre>\n<p>Em nosso <code>blogs<\/code> podemos definir a consist\u00eancia da varredura e, nesse caso, estamos dizendo a ele para esperar at\u00e9 que o \u00edndice seja atualizado antes de retornar os dados. Essa \u00e9 uma opera\u00e7\u00e3o r\u00e1pida, portanto, n\u00e3o pense que ela ser\u00e1 rastreada quando voc\u00ea fizer isso. Apenas n\u00e3o ser\u00e1 t\u00e3o r\u00e1pido quanto o padr\u00e3o.<\/p>\n<p>Nesse ponto, o front-end deve funcionar perfeitamente com o back-end!<\/p>\n<p>Para executar os dois projetos juntos.<\/p>\n<p>Primeiro, verifique se o Couchbase est\u00e1 instalado e se voc\u00ea tem um bucket chamado <code>blog<\/code> criado e o \u00edndice que criamos no tutorial da API.<\/p>\n<p>Em seguida, execute a API REST do Node:<\/p>\n<pre class=\"lang:default decode:true\">servidor de n\u00f3s<\/pre>\n<p>Em seguida, execute o projeto Angular:<\/p>\n<pre class=\"lang:default decode:true\">ng serve<\/pre>\n<p>Registre-se, fa\u00e7a login, crie uma ou duas postagens de blog e verifique se a rota de blogs est\u00e1 mostrando cada um dos blogs que voc\u00ea criou.<\/p>\n<h2>Como voc\u00ea pode melhorar este projeto<\/h2>\n<p>Como mencionamos anteriormente, o projeto poderia usar CSS e layout personalizados, bem como valida\u00e7\u00e3o de formul\u00e1rio e alertas ou notifica\u00e7\u00f5es, caso o usu\u00e1rio tenha tentado usar a senha errada ou o t\u00edtulo do blog exceda um determinado n\u00famero de caracteres, ou se um erro tiver sido lan\u00e7ado porque a API n\u00e3o est\u00e1 sendo executada corretamente.<\/p>\n<p>Criar um <strong>Edi\u00e7\u00e3o do blog<\/strong> p\u00e1gina e rota e um link do t\u00edtulo das postagens do blog na p\u00e1gina <strong>Rota\/p\u00e1gina de blogs<\/strong>.<\/p>\n<p>Criar navega\u00e7\u00e3o e estrutura sofisticadas para o aplicativo.<\/p>\n<p>Reordenar a lista de blogs na se\u00e7\u00e3o <strong>Rota\/p\u00e1gina de blogs<\/strong> ou configurar a capacidade de classificar blogs por t\u00edtulo em ordem crescente ou decrescente.<\/p>\n<p>Permita que os usu\u00e1rios fa\u00e7am login com logins sociais ou use este projeto que criamos e adicione uma rota de portf\u00f3lio e outras p\u00e1ginas de suporte como um ponto de partida para seu pr\u00f3prio portf\u00f3lio de desenvolvedor.<\/p>\n<p>Crie um servi\u00e7o Angular para lidar com o ID da sess\u00e3o, de modo que n\u00e3o seja necess\u00e1rio transmiti-lo a cada evento de navega\u00e7\u00e3o.<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>Voc\u00ea acabou de ver como criar um front-end de cliente simples usando o Angular 11 e o TypeScript para o armazenamento de perfil de usu\u00e1rio que vimos em um <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/creating-user-profile-store-with-node-js-nosql-database\/\" target=\"_blank\" rel=\"noopener noreferrer\">exemplo anterior<\/a>. <span style=\"font-weight: 400\">Cada modelo de perfil de usu\u00e1rio do Angular \u00e9 diferente, \u00e9 claro. Esse front-end de cliente \u00e9 um dos muitos exemplos poss\u00edveis de p\u00e1gina de perfil de usu\u00e1rio de material angular para um front-end, porque esse \u00e9 um aplicativo modular de pilha completa.<\/span>\u00a0Isso significa que o back-end pode estar em qualquer idioma e o front-end pode estar em qualquer idioma.<\/p>\n<p>O c\u00f3digo finalizado est\u00e1 dispon\u00edvel no GitHub em <a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-angular-blog-app\">couchbaselabs \/ couchbase-angular-blog-app<\/a> no GitHub.<\/p>\n<p>Para obter mais informa\u00e7\u00f5es sobre como usar o Couchbase com o Node.js, consulte o <a href=\"https:\/\/developer.couchbase.com\" target=\"_blank\" rel=\"noopener noreferrer\">Portal do desenvolvedor do Couchbase<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>I recently wrote a tutorial titled,\u00a0Creating a User Profile Store with Node.js and a NoSQL Database, as it is a very popular subject and use-case when it comes to NoSQL databases. In that tutorial, we created an API using Node.js [&hellip;]<\/p>","protected":false},"author":63,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,1815,9327],"tags":[1704,2021,1543,2019,1718,2020],"ppma_author":[9032],"class_list":["post-3873","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-best-practices-and-tutorials","category-javascript","tag-angular","tag-front-end","tag-javascript","tag-profile-store","tag-typescript","tag-users"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Create Front-End User Profile Store W\/ Angular &amp; Typescript<\/title>\n<meta name=\"description\" content=\"Create user profile store API and understand how to create a profile page that communicates with each of the API endpoints using TypeScript and Angular.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/creating-front-end-user-profile-store-angular-typescript\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Use TypeScript, Angular as the Front-End for Your User Profile Store\" \/>\n<meta property=\"og:description\" content=\"Create user profile store API and understand how to create a profile page that communicates with each of the API endpoints using TypeScript and Angular.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/creating-front-end-user-profile-store-angular-typescript\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/thepolyglotdeveloper\" \/>\n<meta property=\"article:published_time\" content=\"2017-08-08T14:00:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:15:13+00:00\" \/>\n<meta name=\"author\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Use TypeScript, Angular as the Front-End for Your User Profile Store\",\"datePublished\":\"2017-08-08T14:00:18+00:00\",\"dateModified\":\"2025-06-14T03:15:13+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/\"},\"wordCount\":1663,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"Angular\",\"front-end\",\"javascript\",\"profile store\",\"TypeScript\",\"users\"],\"articleSection\":[\"Application Design\",\"Best Practices and Tutorials\",\"JavaScript\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/\",\"name\":\"Create Front-End User Profile Store W\/ Angular & Typescript\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2017-08-08T14:00:18+00:00\",\"dateModified\":\"2025-06-14T03:15:13+00:00\",\"description\":\"Create user profile store API and understand how to create a profile page that communicates with each of the API endpoints using TypeScript and Angular.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Use TypeScript, Angular as the Front-End for Your User Profile Store\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\",\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy, Developer Advocate, Couchbase\"},\"description\":\"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.\",\"sameAs\":[\"https:\/\/www.thepolyglotdeveloper.com\",\"https:\/\/www.facebook.com\/thepolyglotdeveloper\",\"https:\/\/x.com\/nraboy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/nic-raboy-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Create Front-End User Profile Store W\/ Angular & Typescript","description":"Create user profile store API and understand how to create a profile page that communicates with each of the API endpoints using TypeScript and Angular.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/creating-front-end-user-profile-store-angular-typescript\/","og_locale":"pt_BR","og_type":"article","og_title":"Use TypeScript, Angular as the Front-End for Your User Profile Store","og_description":"Create user profile store API and understand how to create a profile page that communicates with each of the API endpoints using TypeScript and Angular.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/creating-front-end-user-profile-store-angular-typescript\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2017-08-08T14:00:18+00:00","article_modified_time":"2025-06-14T03:15:13+00:00","author":"Nic Raboy, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_misc":{"Written by":"Nic Raboy, Developer Advocate, Couchbase","Est. reading time":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Use TypeScript, Angular as the Front-End for Your User Profile Store","datePublished":"2017-08-08T14:00:18+00:00","dateModified":"2025-06-14T03:15:13+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/"},"wordCount":1663,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["Angular","front-end","javascript","profile store","TypeScript","users"],"articleSection":["Application Design","Best Practices and Tutorials","JavaScript"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/","url":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/","name":"Create Front-End User Profile Store W\/ Angular & Typescript","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2017-08-08T14:00:18+00:00","dateModified":"2025-06-14T03:15:13+00:00","description":"Create user profile store API and understand how to create a profile page that communicates with each of the API endpoints using TypeScript and Angular.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/creating-front-end-user-profile-store-angular-typescript\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Use TypeScript, Angular as the Front-End for Your User Profile Store"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1","name":"Nic Raboy, defensor dos desenvolvedores, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354","url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","caption":"Nic Raboy, Developer Advocate, Couchbase"},"description":"Nic Raboy \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/nic-raboy-2\/"}]}},"authors":[{"term_id":9032,"user_id":63,"is_guest":0,"slug":"nic-raboy-2","display_name":"Nic Raboy, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","first_name":"Nic","last_name":"Raboy","user_url":"https:\/\/www.thepolyglotdeveloper.com","author_category":"","description":"Nic Raboy \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/3873","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=3873"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/3873\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=3873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=3873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=3873"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=3873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}