GithubHelp home page GithubHelp logo

openliberty / guide-rest-client-angular Goto Github PK

View Code? Open in Web Editor NEW
2.0 6.0 4.0 46.07 MB

A guide on how to access a simple RESTful web service and consume its resources with Angular in Open Liberty: https://openliberty.io/guides/rest-client-angular.html

License: Other

JavaScript 98.64% TypeScript 0.84% HTML 0.09% CSS 0.01% Java 0.31% Shell 0.12%

guide-rest-client-angular's Introduction

Consuming a RESTful web service with Angular

Note
This repository contains the guide documentation source. To view the guide in published form, view it on the Open Liberty website.

Explore how to access a simple RESTful web service and consume its resources with Angular in OpenLiberty.

What you’ll learn

Angular is a framework for creating interactive web applications. Angular applications are written in HTML, CSS, and TypeScript, a variant of JavaScript. Angular helps you create responsive and intuitive applications that download once and run as a single web page. Consuming REST services with your Angular application allows you to request only the data and operations that you need, minimizing loading times.

You will learn how to access a REST service and deserialize the returned JSON that contains a list of artists and their albums by using an Angular service and the Angular HTTP Client. You will then present this data using an Angular component.

The REST service that provides the artists and albums resource was written for you in advance and responds with the artists.json.

The Angular application was created and configured for you in the frontend directory. It contains the default starter application. There are many files that make up an Angular application, but you only need to edit a few to consume the REST service and display its data.

Angular applications must be compiled before they can be used. The Angular compilation step was configured as part of the Maven build. You can use the start folder of this guide as a template for getting started with your own applications built on Angular and Open Liberty.

artists.json

link:finish/src/resources/artists.json[role=include]

You will implement an Angular client that consumes this JSON and displays its contents at the http://localhost:9080/app URL.

To learn more about REST services and how you can write them, see Creating a RESTful web service.

Then, point your browser to the web application root http://localhost:9080/app to see the following output:

foo wrote 2 albums:
    Album titled album_one by foo contains 12 tracks
    Album tilted album_two by foo contains 15 tracks
bar wrote 1 albums:
    Album titled foo walks into a bar by bar contains 12 tracks
dj wrote 0 albums:

Starting the service

Before you begin the implementation, start the provided REST service so that the artist JSON is available to you.

Navigate to the start directory to begin.

You can find your artist JSON at the http://localhost:9080/artists URL.

Project configuration

The front end of your application uses Node.js to execute your Angular code. The Maven project is configured for you to install Node.js and produce the production files, which are copied to the web content of your application.

Node.js is server-side JavaScript runtime that is used for developing networking applications. Its convenient package manager, npm, is used to execute the Angular scripts found in the package.json file. To learn more about Node.js, see the official Node.js documentation.

The frontend-maven-plugin is used to install the dependencies listed in your package.json file from the npm registry into a folder called node_modules. The node_modules folder is found in your working directory. Then, the configuration produces the production files to the src/main/frontend/src/app directory.

The src/main/frontend/src/angular.json file is defined so that the production build is copied into the web content of your application.

pom.xml

link:finish/pom.xml[role=include]

Creating the root Angular module

Your application needs a way to communicate with and retrieve resources from RESTful web services. In this case, the provided Angular application needs to communicate with the artists service to retrieve the artists JSON. While there are various ways to perform this task, Angular contains a built-in HttpClientModule that you can use.

Angular applications consist of modules, which are groups of classes that perform specific functions. The Angular framework provides its own modules for applications to use. One of these modules, the HTTP Client module, includes convenience classes that make it easier and quicker for you to consume a RESTful API from your application.

You will create the module that organizes your application, which is called the root module. The root module includes the Angular HTTP Client module.

Create the app.module.ts file.
src/main/frontend/src/app/app.module.ts

app.module.ts

link:finish/src/main/frontend/src/app/app.module.ts[role=include]

The HttpClientModule imports the class into the file. By using the @NgModule tag, you can declare a module and organize your dependencies within the Angular framework. The imports array is a declaration array that imports the HttpClientModule so that you can use the HTTP Client module in your application.

Creating the Angular service to fetch data

You need to create the component that is used in the application to acquire and display data from the REST API. The component file contains two classes: the service, which handles data access, and the component itself, which handles the presentation of the data.

Services are classes in Angular that are designed to share their functionality across entire applications. A good service performs only one function, and it performs this function well. In this case, the ArtistsService class requests artists data from the REST service.

Create the app.component.ts file.
src/main/frontend/src/app/app.component.ts

app.component.ts

link:finish/src/main/frontend/src/app/app.component.ts[role=include]

The file imports the HttpClient class and the Injectable decorator.

The ArtistsService class is defined. While it shares the file of the component class AppComponent, it can also be defined in its own file. The class is annotated by @Injectable so instances of it can be provided to other classes anywhere in the application.

The class injects an instance of the HttpClient class, which it uses to request data from the REST API. It contains the ARTISTS_URL constant, which points to the API endpoint it requests data from. The URL does not contain a host name because the artists API endpoint is accessible from the same host as the Angular application. You can send requests to external APIs by specifying the full URL. Finally, it implements a fetchArtists() method that makes the request and returns the result.

To obtain the data for display on the page, the fetchArtists() method tries to use the injected http instance to perform a GET HTTP request to the ARTISTS_URL constant. If successful, it returns the result. If an error occurs, it prints the error message to the console.

The fetchArtists() method uses a feature of JavaScript called async, await to make requests and receive responses without preventing the application from working while it waits. For the result of the HttpClient.get() method to be compatible with this feature, it must be converted to a Promise by invoking its toPromise() method. APromise is how JavaScript represents the state of an asynchronous operation. If you want to learn more, check out promisejs.org for an introduction.

Defining the component to consume the service

Components are the basic building blocks of Angular application user interfaces. Components are made up of a TypeScript class annotated with the @Component annotation and the HTML template file (specified by templateUrl) and CSS style files (specified by styleUrls.)

Update the AppComponent class to use the artists service to fetch the artists data and save it so the component can display it.

Update the app.component.ts file.
src/main/frontend/src/app/app.component.ts

app.component.ts

link:finish/src/main/frontend/src/app/app.component.ts[role=include]

Replace the entire AppComponent class along with the @Component annotation. Add OnInit to the list of imported classes at the top.

The providers property on the @Component annotation indicates that this component provides the ArtistsService to other classes in the application.

AppComponent implements OnInit, which is a special interface called a lifecycle hook. When Angular displays, updates, or removes a component, it calls a specific function, the lifecycle hook, on the component so the component can run code in response to this event. This component responds to the OnInit event via the ngOnInit method, which fetches and populates the component’s template with data when it is initialized for display. The file imports the OnInit interface from the @angular/core package.

artists is a class member of type any[] that starts out as an empty array. It holds the artists retrieved from the service so the template can display them.

An instance of the ArtistsService class is injected into the constructor and is accessible by any function that is defined in the class. The ngOnInit function uses the artistsService instance to request the artists data. The fetchArtists() method is an async function so it returns a Promise. To retrieve the data from the request, ngOnInit calls the then() method on the Promise which takes in the data and stores it to the artists class member.

Creating the Angular component template

Now that you have a service to fetch the data and a component to store it in, you will create a template to specify how the data will be displayed on the page. When you visit the page in the browser, the component populates the template to display the artists data with formatting.

Create the app.component.html file.
src/main/frontend/src/app/app.component.html

app.component.html

link:finish/src/main/frontend/src/app/app.component.html[role=include]

The template contains a div element that is enumerated by using the ngFor directive. The artist variable is bound to the artists member of the component. The div element itself and all elements contained within it are repeated for each artist, and the {{ artist.name }} and {{ artist.albums.length }} placeholders are populated with the information from each artist. The same strategy is used to display each album by each artist.

Building the front end

The Open Liberty instance is already started, and the REST service is running. In a new command-line session, build the front end by running the following command in the start directory:

mvn generate-resources

The build might take a few minutes to complete. You can rebuild the front end at any time with the generate-resources Maven goal. Any local changes to your TypeScript or HTML are picked up when you build the front end.

Point your browser to the http://localhost:9080/app web application root to see the following output:

foo wrote 2 albums:
    Album titled album_one by foo contains 12 tracks
    Album tilted album_two by foo contains 15 tracks
bar wrote 1 albums:
    Album titled foo walks into a bar by bar contains 12 tracks
dj wrote 0 albums:

If you use the curl command to access the web application root URL, you see only the application root page in HTML. The Angular framework uses JavaScript to render the HTML to display the application data. A web browser runs JavaScript, and the curl command doesn’t.

Testing the Angular client

No explicit code directly uses the consumed artist JSON, so you don’t need to write any test cases.

Whenever you change and build your Angular implementation, the application root at http://localhost:9080/app reflects the changes automatically.

When you are done checking the application root, exit dev mode by pressing CTRL+C in the command-line session where you ran the Liberty.

Although the Angular application that this guide shows you how to build is simple, when you build more complex Angular applications, testing becomes a crucial part of your development lifecycle. If you need to write test cases, follow the official unit testing and end-to-end testing documentation on the official Angular page.

Great work! You’re done!

You just accessed a simple RESTful web service and consumed its resources by using Angular in Open Liberty.

guide-rest-client-angular's People

Contributors

gkwan-ibm avatar evelinec avatar dependabot[bot] avatar realmodusoperandi avatar tt-le avatar reecenana avatar jj-zhang avatar davidwyao avatar kevcpro avatar shin19991207 avatar nimg98 avatar poojasaji1 avatar yeekangc avatar jakub-pomykala avatar saumyapandyaa avatar t27gupta avatar

Stargazers

 avatar Prafull Kotecha avatar

Watchers

James Cloos avatar  avatar Alasdair Nottingham avatar Chuck Bridgham avatar  avatar  avatar

guide-rest-client-angular's Issues

Content review checklist

Content Review:

Review of the content and structure of the guide by a senior technical member to ensure the direction, flow and quality of the guide meet the requirements and expectations.

  • Ensure guide's content coverage is adequate and suffice requirements
  • Ensure code are structured well according to best practices
  • Ensure direction of the guide is accurate
  • Ensure flow of the guide is smooth
  • Ensure requirements (purpose and goal) are clearly stated
  • Ensure instructions make sense and are easy to understand
  • Ensure concepts are being explained clearly first before describing what to learn
  • Ensure the guide aligns with Open Liberty strategy
  • Ensure the guide is consistent with other guides, especially the ones in the same category
  • Ensure the instructions explain the why besides the what questions, identify areas that are not clear and hard to follow in first pass
  • Ensure the guide in general follow and convey best practices and in line with accepted norms
  • Ensure the title and abstract are well stated
  • Ensure the guide has good Search Engine Optimization (SEO)

GK feedback for the Content review

  • Switch the order of the first 2 introduction paragraphs

    • currently
      • 1: "You'll learn ..."
      • 2: "Angular is ..."
    • suggestion:
      • 2: "Angular is ..."
      • 1: "You'll learn ..."
  • the TypeScript link "https://typescriptlang.org" cannot be reached

  • In the following statement, should use and between responsive, intuitive instead of comma?

    • "Angular helps you create responsive, intuitive applications..."
  • no need to have the JDK 9 dependencies in the pom.xml

  • failed on mac to run 'mvn install` at the start directory without change anything, but works fine on the finish directory

[INFO] --- frontend-maven-plugin:1.7.6:npm (npm run build) @ io.openliberty.guides.consumingrest-ng ---
[INFO] Running 'npm run build' in /Users/gkwan/tasks/CNAI/guides/testsite/guide-rest-client-angular/start/src/main/frontend
[INFO] 
[INFO] > [email protected] build /Users/gkwan/tasks/CNAI/guides/testsite/guide-rest-client-angular/start/src/main/frontend
[INFO] > ng build --base-href="/app/"
[INFO] 
[ERROR] sh: ng: command not found
[ERROR] npm ERR! file sh
[ERROR] npm ERR! code ELIFECYCLE
[ERROR] npm ERR! errno ENOENT
[ERROR] npm ERR! syscall spawn
[ERROR] npm ERR! [email protected] build: `ng build --base-href="/app/"`
[ERROR] npm ERR! spawn ENOENT
[ERROR] npm ERR! 
[ERROR] npm ERR! Failed at the [email protected] build script.
[ERROR] npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
[ERROR] 
[ERROR] npm ERR! A complete log of this run can be found in:
[ERROR] npm ERR!     /Users/gkwan/.npm/_logs/2019-05-15T17_33_23_849Z-debug.log
  • warning on linux when run mvn install
[WARNING] npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
[WARNING] npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
[ERROR] 
[INFO] added 1086 packages from 1026 contributors and audited 42611 packages in 33.519s
  • The instructions in "Update the app.module.ts file." and "Update the app.component.ts file." sections are not clear. Suggest to change "Update" to "Replace". Or do something like the "update" in the "Enabling explicit distributed tracing" section of https://openliberty.io/guides/microprofile-opentracing.html

  • Because the application is provided by the guide (i.e. the guide does not ask readers to create), better make content clear in use of the word "your". Suggest the following changes:

    • In the section "Importing the HTTP client",
      • change "In the case of this guide, your application ..." to "...guide, the provided Angular application ..."
      • change "Your application is organized into a module..." to "The application is ..." or "The provided application is ..."
      • change "... into your module ..." to "... into the root module ..."
      • change "... from your application’s code." to "... from the application’s code."
    • In the section "Creating the Angular component",
      • change "You will create the component in your application..." to "You will need to create the Angular component in your application..."
      • change "This file ..." to "The component file..."
      • change "The default Angular application ..." to "The provided Angular application ..."
      • change "First, import two classes you’ll need for the service: HttpClient and Injectable." to "First, import the HttpClient and Injectable classes for the artists service."
      • change "Finally, update the AppComponent class to use this service." to "Finally, update the AppComponent class to use the artists service."
      • Does the word "rest" in "...the rest of the application." mean "the part that is left after" or "REST service" or something?
      • Should "... on the promise and provide..." to "... on the Promise and provide..."?
    • In the section "Creating the Angular component template"
      • Can rewording the first whole statement "Now that ..."? It is not clear to me.
      • "Replace the template of your component." Why is a html file? In the context, As a reader, I think "component" is the app.component.ts. Should say "Replace the template of the component HTML file."?
      • "this file" in "The Angular application is already set up to display the contents of this file." means which file?
      • "Replace the Angular "Hello" HTML". As a reader, I do not realize what "Hello" HTML means or reference to which, because it is not mentioned in above content.
  • page-seo-description should be improved

Review feedback

What you'll learn

  • It may be good to move the paragraph about Angular in "Angular is a framework for creating interactive web applications.." as the second paragraph in this section to explain right away what is Angular after the intro of the guide.

  • In this section, try to explain why user wants to use Angular to cosume a RESTful web service?

Importing the HTTP client

  • Navigate to the start directory to begin. => backtick start

  • Angular applications consist of modules; each module declares all other modules that it imports or exports. AppModule is the root module, and most apps import HttpClientModule here. => This statement seem unclear, especially "most apps import HttpClientModule here" is confusing. Would be good to explain why HttpClientModule is imported here and/or what does it do?

Creating the Angular component

  • To obtain the data for display on the page, fetchArtists() Tries to use the injected http instance to perform a GET HTTP request to the ARTISTS_URL and returning the result.
    => perhaps fetchArtists() method can have a hotspot
    => "Tries" should be lower case

  • If an error occurs,it prints the message of the error to the console. => a space is needed after the comma

  • the result of the HttpClient.get() method must be converted to a Promise using toPromise(). => the toPromise() can have a hotspot

  • To retrieve the data from the request, call then() on the promise and provide a function that will take in the data and store it to the artists class member. => the artists class can have a hotspot

Creating the Angular component template

  • The app.component.html file shows up empty on the code column. I think the problem is with the tags used in the include statement, in include::finish/src/main/frontend/src/app/app.component.html[tags=html]. There's no html tags defined in the app.component.html file, so no need to use the tags. You can see the draft guide content on our staging site at https://draft-guides.mybluemix.net/guides/rest-client-angular.html.

  • Followed the guide to the following point (working in the start directory), the http://localhost:9080/app URL gives "Context root not found" error message..

After everything is set up, point your browser to the web application root http://localhost:9080/app to see the following output:

foo wrote 2 albums:
    Album titled album_one by foo contains 12 tracks
    Album tilted album_two by foo contains 15 tracks
bar wrote 1 albums:
    Album titled foo walks into a bar by bar contains 12 tracks
dj wrote 0 albums:

General application code

  • There are lots of files under the src/main/frontend directory, but only the app.module.ts and app.component.ts files are being described in the guide. What are the other files used for? Can some of them be cleaned up?

  • There are a number of files under src/main/webapp/app directory as well, and they're not being referred to in the guide. Are these files needed, and should be explained in the guide?

Pre-publishing tasks

Pre-Publishing Tests

  • Check appearance (contents, headings, paragraphs, code snippets, outputs, links, hotspots) of the guide on test site, ie, qa-guides
  • Read through the guide
  • Clone repo and test start directory with no error
  • Run diff -r start/ finish/
  • Follow the instruction in the guide to test that it is working
  • Use the copy buttons instead of typing
  • Check that the release date on the readme.adoc is the publishing date

End to end test issues

  • The guide doesn't specifically ask users to add the @Injectable() annotation or update the @Component() annotation for the app.components.ts file. This caused my web application root to show a blank page (http://localhost:9080/app).

SME review feedback

  • "One of these, the HTTP Client module, includes the classes you need to consume a RESTful API from your application." is a bit misleading since you don't actually need it since you could just do it via vanilla js. I would instead say something like "... classes that will make it easier to ...." or "...the HTTP Client module, includes convenience classes that will make it easier and quicker to consume a RESTful API from your application."

  • change ARTISTS_URL to = '/artists';

  • take a look if everything is correct as there are some 503s when it was trying to fetch things (when running the mvn generate-resources command - see message below that was run on a Windows environment)

$ mvn generate-resources
[INFO] Scanning for projects...
Downloading from liberty-starter-maven-repo: http://liberty-app-accelerator.wasdev.developer.ibm.com/start/api/v1/repo/net/wasdev/wlp/maven/parent/liberty-maven-app-parent/maven-metadata.xml
[WARNING] Could not transfer metadata net.wasdev.wlp.maven.parent:liberty-maven-app-parent/maven-metadata.xml from/to liberty-starter-maven-repo (http://liberty-app-accelerator.wasdev.developer.ibm.com/start/api/v1/repo): Failed to transfer file: http://liberty-app-accelerator.wasdev.developer.ibm.com/start/api/v1/repo/net/wasdev/wlp/maven/parent/liberty-maven-app-parent/maven-metadata.xml. Return code is: 503 , ReasonPhrase:Service Unavailable.
Downloading from liberty-starter-maven-repo: http://liberty-app-accelerator.wasdev.developer.ibm.com/start/api/v1/repo/io/openliberty/features/features-bom/maven-metadata.xml
[WARNING] Could not transfer metadata io.openliberty.features:features-bom/maven-metadata.xml from/to liberty-starter-maven-repo (http://liberty-app-accelerator.wasdev.developer.ibm.com/start/api/v1/repo): Failed to transfer file: http://liberty-app-accelerator.wasdev.developer.ibm.com/start/api/v1/repo/io/openliberty/features/features-bom/maven-metadata.xml. Return code is: 503 , ReasonPhrase:Service Unavailable.
[WARNING]
[WARNING] Some problems were encountered while building the effective model for io.openliberty.guides:io.openliberty.guides.consumingrest-ajs:war:1.0-SNAPSHOT
[WARNING] 'dependencyManagement.dependencies.dependency.version' for io.openliberty.features:features-bom:pom is either LATEST or RELEASE (both of them are being deprecated) @ line 35, column 26
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building io.openliberty.guides.consumingrest-ajs 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- frontend-maven-plugin:1.7.6:install-node-and-npm (install node and npm) @ io.openliberty.guides.consumingrest-ajs ---
[INFO] Node v10.15.3 is already installed.
[INFO] NPM 6.4.1 is already installed.
[INFO]
[INFO] --- frontend-maven-plugin:1.7.6:npm (npm install) @ io.openliberty.guides.consumingrest-ajs ---
[INFO] Running 'npm install' in C:\openLiberty.io\guide-rest-client-angular\start\src\main\frontend
[WARNING] npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):
[WARNING] npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
[ERROR]
[INFO] audited 42611 packages in 5.842s
[INFO] found 1 high severity vulnerability
[INFO]   run `npm audit fix` to fix them, or `npm audit` for details
[INFO]
[INFO] --- frontend-maven-plugin:1.7.6:npm (npm run build) @ io.openliberty.guides.consumingrest-ajs ---
[INFO] Running 'npm run build' in C:\openLiberty.io\guide-rest-client-angular\start\src\main\frontend
[INFO]
[INFO] > [email protected] build C:\openLiberty.io\guide-rest-client-angular\start\src\main\frontend
[INFO] > ng build --base-href="/app/"
[INFO]
[INFO]
[INFO] Date: 2019-05-06T16:37:01.634Z
[INFO] Hash: 583e17159a2c0025385b
[INFO] Time: 6369ms
[INFO] chunk {es2015-polyfills} es2015-polyfills.js, es2015-polyfills.js.map (es2015-polyfills) 284 kB [initial] [rendered]
[INFO] chunk {main} main.js, main.js.map (main) 10.2 kB [initial] [rendered]
[INFO] chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 236 kB [initial] [rendered]
[INFO] chunk {runtime} runtime.js, runtime.js.map (runtime) 6.08 kB [entry] [rendered]
[INFO] chunk {styles} styles.js, styles.js.map (styles) 16.3 kB [initial] [rendered]
[INFO] chunk {vendor} vendor.js, vendor.js.map (vendor) 3.29 MB [initial] [rendered]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 05:17 min
[INFO] Finished at: 2019-05-06T11:37:01-05:00
[INFO] Final Memory: 10M/16M
[INFO] ------------------------------------------------------------------------
  • We could look into expanding the client set of guides to all the CRUD operations and not just GET, but it can be a low priority

Content wise, it's good; it mirrors what we do with the other "Consuming REST..." guides.

TDB issues

This issue to note the few things that were found during testing of this guide that may require further investigation:

  • The first time the mvn install command is run to build the app, there's a red error message show up in the console log.

[Mac]

[INFO] --- frontend-maven-plugin:1.7.6:npm (npm install) @ io.openliberty.guides.consumingrest-ajs ---
[INFO] Running 'npm install' in /Users/evelinec/OLG/testing/temp/draft-guide-rest-client-angular/start/src/main/frontend
[INFO] 
[INFO] > [email protected] install /Users/evelinec/OLG/testing/temp/draft-guide-rest-client-angular/start/src/main/frontend/node_modules/fsevents
[INFO] > node install
[INFO] 
[ERROR] node-pre-gyp WARN Using request for node-pre-gyp https download 
[INFO] [fsevents] Success: "/Users/evelinec/OLG/testing/temp/draft-guide-rest-client-angular/start/src/main/frontend/node_modules/fsevents/lib/binding/Release/node-v64-darwin-x64/fse.node" is installed via remote
[INFO] 

The second time running the command, you don't see the error, but have the following message:

[INFO] --- frontend-maven-plugin:1.7.6:npm (npm install) @ io.openliberty.guides.consumingrest-ajs ---
[INFO] Running 'npm install' in /Users/evelinec/OLG/testing/temp/draft-guide-rest-client-angular/start/src/main/frontend
[INFO] audited 42611 packages in 5.796s
[INFO] found 1 high severity vulnerability
[INFO]   run `npm audit fix` to fix them, or `npm audit` for details

[Windows]

[INFO] --- frontend-maven-plugin:1.7.6:npm (npm install) @ io.openliberty.guides.consumingrest-ajs ---
[INFO] Running 'npm install' in C:\openLiberty.io\guide-rest-client-angular\start\src\main\frontend
[WARNING] npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):
[WARNING] npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
[ERROR]
[INFO] audited 42611 packages in 5.842s
[INFO] found 1 high severity vulnerability
[INFO]   run `npm audit fix` to fix them, or `npm audit` for details
  • There are a number of files under src/main/webapp/app directory after building and running the application.
    => The first response is, these files are the output of the Angular compiler and must be present at the root of the .war file in order for them to be served properly. I think these should be placed in the target directory but I am not a maven expert and was unable to find how to copy them to directly to the SNAPSHOT.war folder within target. I can investigate further if you'd like, but the folder is at least ignored in the .gitignore file.

Navigating to http://localhost:9080/app after server is started shows nothing on MacOS BigSur

On Macbook Pro with MacOS BigSur, following your instructions and after running mvn liberty:run, server successfully started without any errors. However, navigating to http://localhost:9080/app does nothing. It ends up in endless reload icon spinning in browser and nothing shows.

Here is output after server successfully started:

[INFO] Launching defaultServer (Open Liberty 21.0.0.8/wlp-1.0.55.cl210820210727-1323) on OpenJDK 64-Bit Server VM, version 15.0.1+9 (en_CA)
[INFO] [AUDIT   ] CWWKE0001I: The server defaultServer has been launched.
[INFO] [AUDIT   ] CWWKZ0058I: Monitoring dropins for applications.
[INFO] [AUDIT   ] CWWKT0016I: Web application available (default_host): http://192.168.1.73:9080/
[INFO] [AUDIT   ] CWWKZ0001I: Application guide-rest-client-angular started in 0.337 seconds.
**[INFO] [ERROR   ] CWWKO0221E: TCP Channel defaultHttpEndpoint initialization did not succeed.  The socket bind did not succeed for host * and port 9080.  The port might already be in use.  Exception Message: Address already in use**
[INFO] [AUDIT   ] CWWKT0017I: Web application removed (default_host): http://192.168.1.73:9080/
[INFO] [AUDIT   ] CWWKF0012I: The server installed the following features: [jaxrs-2.1, jaxrsClient-2.1, jsonp-1.1, servlet-4.0].
[INFO] [AUDIT   ] CWWKF0011I: The defaultServer server is ready to run a smarter planet. The defaultServer server started in 2.164 seconds.

After killing the process that was using port 9080 (kill -9 :9080) and reissuing mvn liberty:run, get error:[INFO]

CWWKE0005E: The runtime environment could not be launched.
[INFO] CWWKE0029E: An instance of server defaultServer is already running.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  32.111 s
[INFO] Finished at: 2021-08-31T09:37:21-07:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal io.openliberty.tools:liberty-maven-plugin:3.3.4:run (default-cli) on project guide-rest-client-angular: CWWKM2002E: Failed to invoke [/Users/dinob/Desktop/angular-openliberty/guide-rest-client-angular/finish/target/liberty/wlp/bin/server, run, defaultServer]. RC= 1 but expected=0. -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

Guide Updates

  • The initial build of the frontend in Starting the service seems unnecessary.

  • Add a project configuration section (or subsection). Users should be aware of which resources they are generating as it is not intuitive since the OL server is not responsible for building the frontend.

  • In Creating the Angular component the app.component.ts file is updated twice, despite the section suggesting the creation of the component. Updating the same file twice in the same section can also seem redundant (despite the update being in their own subsections).

    The guide goes into some detail about the way the data is displayed, which I think can also be reduced as the focus should be the http client. If the data was displayed for UX, then a high-level explanation of that syntax is necessary, but the data is only displayed as plain text.

    Can also consider displaying the returned data in a more meaningful way.

  • front end -> frontend

Peer review feedback

Application code feedback

  • Not sure the Reader.java class in src/main/java/io/openliberty/guides/consummingrest/service/Reader.java is needed. If not, it'd be clean up.

  • All license header on the files that have been updated, should be changed to the current year, ie, Copyright (c) 2019 IBM Corporation and others. But looks like the service classes aren't changed from the previous version, they do not need changes.

  • The application name in the server.xml file may need to be updated to more relevant to this guide. Currently having io.openliberty.guides.consumingrest-ajs.war, which is from the AngularJS server config file?

  • Same as above for the <artifactId>io.openliberty.guides.consumingrest-ajs</artifactId> in the pom.xml

  • Some comments in the pom.xml may need to be finalize? ie,

<!-- NB! Set <version> to the latest released version of frontend-maven-plugin, like in README.md -->

Draft feedback

  • Consider update the :guide-author: Open Liberty field to the Author's name?

  • Consider adding the SEO title and description attributes in the README.adoc for this guide:

:page-seo-title: Consuming RESTful web services with Angular
:page-seo-description: A tutorial on how to consume your microservices with Angular
  • Acrolinx (ID checker tool) suggestions:
  • spell "frontend" as "front end" for noun or "front-end" for adjective
  • use contractions instead of the full form, ie, "do not" as "don't"
  • simply word for "a variety of" to "various"
  • "This file will contain two classes: the service, which will handle data
    access, and the component itself, which will handle presenting the data.The default
    Angular application already contains a component.` => missing space after the first sentence
  • change "class which" to "class, which" or "class that"
  • change "execute" to "run", "start" or "enter"

Review feedback

(1)

The class injects an instance of the HttpClient class, which it will use to request data from the REST API. It contains a constant ARTISTS_URL which points to the API endpoint it will request data from. Finally, it implements a method fetchArtists() that makes the request and returns the result.

To obtain the data for display on the page, fetchArtists() tries to use the injected http instance to perform a GET HTTP request to the ARTISTS_URL and returning the result. If an error occurs, it prints the message of the error to the console.

Looks like we default to localhost. (Well, the service is local anyway.) . Useful to call this out and also indicate what needs to be done if the service isn't local.

(2)

Although this guide didn’t teach you how to build logic, you will likely build logic when you develop your own applications, and testing will become a crucial part of your development lifecycle. If you need to write test cases, follow the official unit testing and end-to-end testing documentation on the official Angular page.

It took me a while to parse "build logic". Perhaps there is better way to phrase it.

Post-Publishing Tests

Post-Publishing Tests (Nimrah)

  • Check appearance (contents, headings, paragraphs, code snippets, outputs, links) of the guide on openliberty.io
  • Clone repo and test finish directory with no error

Other post-publishing tasks (to be done by the Admin Team) (Eveline)

  • Add description for the repo with link to guide's published website

  • Double check the SEO title and description are added for the guide

  • Ensure automated test for PR and Continuous Tests are on Travis, see instruction

  • Enable pull creation notification on the repo for was-lib-guides-alerts, see instruction

  • Enable master and qa branches lock down, see instruction

  • Add the new guide's repo to the OpenLiberty/guides-common ZenHub board

  • Delete dev branch

  • (Optional) Send announcement to slack channel(s)

  • Arrange a demo at the EOI meeting

The app root URL is not accessible with curl

On Linux and Windows, running the mvn generate-resources command to build the front end had the follow error:

[WARNING] npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
[WARNING] npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
[ERROR] 
[INFO] added 1099 packages from 1028 contributors and audited 43177 packages in 32.881s
[INFO] found 12 vulnerabilities (1 low, 1 moderate, 10 high)
[INFO]   run `npm audit fix` to fix them, or `npm audit` for details

Accessing the web app root http://localhost:9080/app from a browser shows the correct result. But this URL is not accessible via the curl command. It gives the 302 code. This happens on both Mac and Linux. This issue happens with the original app; it's not to do with dev mode conversion.

Peer review checklist

Peer Review: review to be done by a peer member.

  • Check that the guide has working instruction and sample code
  • Check the quality of code according to the best coding practices
  • Check the quality and presentation of guide according to Structure and Style Guideline
  • Check the consistency of guide with template and other guides
  • Examples with the right outcomes are provided
  • Example with the wrong outcomes, if any, are provided
  • Check that all licensing statements are properly stated in all files
  • Check that the pom.xml, server.xml, etc files are clean
  • Check that the directories are properly structured
  • Test the guide on 3 platforms: Mac, Win, Linux
  • If any URL visits, try them on different browsers: Firefox, Chrome, Safari
  • If any URL visits, try curl command where applicable
  • Ensure that the guide is using the latest version of the liberty-maven-plugin or liberty-gradle-plugin where applicable
  • Check that some of these page-tags are used in a guide: MicroProfile, Maven, Docker, Kubernetes, Gradle, Java EE, Security. Only these tags are visible on the website. Latest list here.
  • Check the attribution statement is accurate for the guide

Peer Testing: tests to be done by a peer member.

Guide’s contributor’s (if available, otherwise peer tester’s) responsibility:

  • Run Acrolink Checker on draft (above 70 score approximately)
  • Consider SEO title and description for the guides
  • Ensure automated test is enable, set up with Travis CI, and able to schedule tests
  • Run diff -r start/ finish/ and there's no differences
  • Ensure that the automation tests are able to run with continuous daily builds

Peer Tester’s responsibility:

  • Check the appearance of the guide on test site for the following items:
  • Table of contents
  • Headings
  • Paragraphs
  • code snippets
  • outputs
  • links
  • hotspots
  • Test the guide end-to-end with working instruction and sample code
  • Perform all the defined test cases

Publishing tasks

Publishing Tasks

  • Create a PR from dev to mater branch

  • Create qa branch from master branch

  • Rename the guide repo

  • Refresh qa staging site and verify

  • Request to refresh openliberty.io site

  • For master branch, add a tag by creating a new release for this repo with name "1st-release"

User Guide Review

Time: 20 minutes

Creating the Angular component

Defining a service to fetch data

  • ArtistsService shouldn't included the annotation above for hotspot
  • Under the first arrow, ArtistsService class and AppComponent class are hotspoted differently, should be the same for consistency. AppComponent should probably highlight the entire class
  • Under the first arrow, fourth paragraph, the first sentence, in the end "and returning the result." Probably shouldn't use present continuous tense.
  • People might not be familiar with what a Promise is if they are not familiar with Angular. Some explanation or links could be helpful

Defining a component to consume a service

  • One of the AppComponent does not have hotspot.

User Testing Checklist

  • Record the time it takes to go through the entire guide
  • Test each step in the guide is clear to understand
  • Ensure no logic errors
  • Resolve anything that does not work
  • Resolve anything usability issues (confusing or hard to follow)
  • Achieve basic understanding/working knowledge of the topic in the guide

artist vs artists

Under "Creating the Angular component template", we have:

The artists variable is bound to the artists member of the component.

Should one of the artists be artist?

The guide is extremely simple and lacking useful information

Since this is a guide on open liberty and angular talking together, a walkthrough for setting up open liberty would be helpful since there is not much outthere about it as it is not as widely used compare to Angular for which we can find this information all over the place.

Providing projects that are already setup without providing a guidance how to do so is not very helpful other than just demonstrating that liberty can do it. It would also provide guidance and clarifications to issues like this https://stackoverflow.com/questions/49394151/how-to-use-angular-with-liberty-websphere-server but for Angular rather than AngularJS

It would be more helpful for this article to have a step by step guide on:

  1. How to install and setup OpenLiberty on local machine
  2. How to setup its setting files like server.xml with detailed information
  3. How to run it, stop it
  4. How to create a simple JakartaEE or Springboot REST API
  5. How to host it on OpenLiberty server
  6. How to create an Angular app that has little bit more content than current example
  7. How to run it and do CRUD operations talking to the JakartaEE or Springboot REST API on OpenLiberty server

I think this would significantly improve learning experience and adoption of OpenLiberty

Error message shows up in a fresh env

Start the app server on this guide and visit the http://localhost:9080/artists URL for the very first time in a fresh env and the follow error shows up. Found on Mac, Linux and Windows:

[INFO] [WARNING ] SRVE0190E: File not found: /app
[INFO] [ERROR   ] Error Page Exception: 
[INFO]                                                                                                                guide-rest-client-angular
[INFO]                                                                                                                /
[INFO]                                                                                                                Error Page Exception
[INFO]                                                                                                                com.ibm.ws.webcontainer.webapp.WebAppErrorReport: java.io.FileNotFoundException: SRVE0190E: File not found: /app
[INFO] 	at com.ibm.ws.webcontainer.extension.DefaultExtensionProcessor.handleRequest(DefaultExtensionProcessor.java:493)
[INFO] 	at [internal classes]
[INFO] Caused by: java.io.FileNotFoundException: SRVE0190E: File not found: /app
[INFO] 	... 3 more
[INFO] 
[2019-11-28, 12:02:22:365 EST] 00000049 com.ibm.ws.webcontainer.extension                            W SRVE0190E: File not found: /app
[2019-11-28, 12:02:22:613 EST] 00000049 com.ibm.ws.logging.internal.impl.IncidentImpl                I FFDC1015I: An FFDC Incident has been created: "java.io.FileNotFoundException: SRVE0190E: File not found: /app com.ibm.ws.webcontainer.webapp.WebApp.handleError 912" at ffdc_19.11.28_12.02.22.0.log
[2019-11-28, 12:02:22:618 EST] 00000049 com.ibm.ws.webcontainer.webapp                               E Error Page Exception: 
                                                                                                               guide-rest-client-angular
                                                                                                               /
                                                                                                               Error Page Exception
                                                                                                               com.ibm.ws.webcontainer.webapp.WebAppErrorReport: java.io.FileNotFoundException: SRVE0190E: File not found: /app
	at com.ibm.ws.webcontainer.webapp.WebApp.sendError(WebApp.java:4355)
	at com.ibm.ws.webcontainer.webapp.WebApp.handleException(WebApp.java:5106)
	at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:5086)
	at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.handleRequest(DynamicVirtualHost.java:314)
	at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:1007)
	at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.run(DynamicVirtualHost.java:279)
	at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:1136)
	at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.wrapHandlerAndExecute(HttpDispatcherLink.java:417)
	at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.ready(HttpDispatcherLink.java:376)
	at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:547)
	at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleNewRequest(HttpInboundLink.java:481)
	at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.processRequest(HttpInboundLink.java:346)
	at com.ibm.ws.http.channel.internal.inbound.HttpICLReadCallback.complete(HttpICLReadCallback.java:70)
	at com.ibm.ws.tcpchannel.internal.WorkQueueManager.requestComplete(WorkQueueManager.java:503)
	at com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:573)
	at com.ibm.ws.tcpchannel.internal.WorkQueueManager.workerRun(WorkQueueManager.java:954)
	at com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker.run(WorkQueueManager.java:1043)
	at com.ibm.ws.threading.internal.ExecutorServiceImpl$RunnableWrapper.run(ExecutorServiceImpl.java:239)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.io.FileNotFoundException: SRVE0190E: File not found: /app
	at com.ibm.ws.webcontainer.extension.DefaultExtensionProcessor.handleRequest(DefaultExtensionProcessor.java:493)
	at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1218)
	at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1002)
	at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:1410)
	at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:171)
	at com.ibm.ws.webcontainer.webapp.WebApp.sendError(WebApp.java:4310)
	... 20 more

[2019-11-28, 12:03:30:072 EST] 0000001d com.ibm.ws.kernel.launch.internal.ServerCommandListener      A CWWKE0055I: Server shutdown requested on Thursday, November 28, 2019 at 12:03 p.m.. The server defaultServer is shutting down.

Afterwards, it's not reproducible.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.