Presentation
Presentation
Presentation
DSpace 7:
Advanced Training
Architecture
Front End
Web Browser 1 Initial Request
4 Return JSON
Architecture
Front End
Web Browser 1 Initial Request
ge Assetstore
t pa
nex
urn
Ret
4
DSpace 7 UI demo
https://dspace7-demo.atmire.com/
(uses the REST API demo as backend)
https://angular.io/tutorial
Angular Concepts
https://angular.io/docs/ts/latest/
Building / Running Angular Apps
https://angular.io/docs/ts/latest/guide/template-syntax.html
Example Template
1 <div *ngIf="topLevelCommunities.hasSucceeded | async">
2 <h2>{{'home.top-level-communities.head' | translate}}</h2>
<p class="lead">{{'home.top-level-communities.help' | translate}}</p>
<ul>
3 <li *ngFor="let community of (topLevelCommunities.payload | async)">
<p>
4 <span class="lead"><a [routerLink]="['/communities', community.id]">
{{community.name}}</a></span><br>
5 <span class="text-muted">{{community.shortDescription}}</span>
</p>
</li>
...
Template Syntax Hints
{{obj.value}}
Prints value of “obj.value” expression/variable
<div [class]="obj.class"> [Property binding]
Sets HTML attr “class” to value of “obj.class”
Square brackets set a property
<button (click)="doThing($event)"> (Event binding)
Call “doThing()” method (in component) when click is triggered
Parentheses respond to an *event*
<my-component [(title)]="name">
Two way binding. Sets property “title” to name, and updates “name”
if title is changed (i.e. “titleChange” event is triggered)
<my-component [title]="name" (titleChange)="name=$event">
Template Syntax Hints
<div *ngIf="showSection">
Only display this <div> if “showSection” is true
<li *ngFor="let item of list">
Display a <li> for every “item” in “list”.
<div [ngClass]="{‘active’: isActive}">
Set the HTML “class” to “active”, if “isActive” is true
https://angular.io/guide/template-syntax
https://angular.io/guide/cheatsheet
Angular: Main elements
● Collection list
component
● Specific metadata
field components
(extend shared one)
<main>
...
</main>
<ds-footer></ds-footer>
</div>
Component’s Class
1 @Component({
2 selector: 'ds-header',
3 styleUrls: ['header.component.css'],
4 templateUrl: 'header.component.html'
})
5 export class HeaderComponent implements OnInit {
isNavBarCollapsed: boolean;
...
6 ngOnInit(): void {
7 this.isNavBarCollapsed = true;
}
8 toggle(): void {
this.isNavBarCollapsed = !this.isNavBarCollapsed;
}
Component’s Template
1 <button (click)="toggle()" aria-controls="collapsingNav">
<i class="fa fa-bars fa-fw" aria-hidden="true"></i>
</button>
2 <div id="collapsingNav" [ngbCollapse]="isNavBarCollapsed">
3 <a class="nav-link" routerLink="/home"
routerLinkActive="active">
{{ 'header.home' | translate }}
</a>
</div>
Angular: Main elements
https://github.com/DSpace/dspace-angular/
Hands-on Prerequisites
Instructions on
https://tinyurl.com/or2019-dspace7-wiki
DSpace-Angular: Folder structure
/
config/ (configuration files)
resources/ (static files, e.g. i18n, images)
src/app/ (Angular application source code)
src/backend/ (mock REST data)
src/platform/ (root Angular modules for client/server)
dist/ (compiled application created by yarn/npm)
DSpace-Angular: /src/app
/src/app
• Each “feature” is in a separate subfolder
• File naming convention
– header.component.ts (Header component class)
– header.component.html (Header component template)
– header.component.scss (Header component styles)
– header.component.spec.ts (Header comp specs / tests)
– community-page.module.ts (Community Page module
definition)
– dspace-rest-v2.service.ts (REST API service
definition)
Package.json: build scripts
– change @rendersItemType('Publication', …)
to @rendersItemType('DataPackage', ItemViewMode.Full)
</ds-metadata-field-wrapper>
DataPackage relations
• in data-package.component.ts:
– Add a field: dataFiles$: Observable<Item[]>;
– And populate it:
this.dataFiles$ = this.resolvedRelsAndTypes$.pipe(
filterRelationsByTypeLabel('isDataFileOfDataPackage'),
relationsToItems(this.item.id, this.ids)
);
Observables
• this.resolvedRelsAndTypes$ is an observable
– it contains a mapping of relationshipTypes and their
relationships
– “observable” means its value can change over time
– It will change when the server responds with
relationship data.
Piping observables
• filterRelationsByTypeLabel('isDataFileOfDataPackage')
will only let through relationship objects of the
type isDataFileOfDataPackage
• relationsToItems(this.item.id, this.ids) will use those
relationship objects to retrieve the Items they
link to
DataPackage relations
• in data-file.component.ts
– change @rendersItemType('DataPackage', …)
to @rendersItemType('DataFile', ItemViewMode.Full)
• in data-file.component.ts
– rename dataFiles$ to dataPackages$
– filter by isDataPackageOfDataFile instead
The DataFile component
• in data-file.component.html
– Replace Data Package: With Data File:
– Remove the prism.publicationName field
– Replace the dataFiles$ relation with
dataPacakges$ and update the label
The DataFile component
• In src/app/+item-page/item-page.module.ts
– Add the new component to the declarations
and entryComponents sections.
The DataFile component
• https://augury.angular.io
• Component tree
– see component properties
– assign a component to a var in the console
– See dependency injection graphs
• Router tree
– see route structure as a graph
Browser Extensions:
redux-devtools
• https://github.com/gaearon/redux-devtools
https://github.com/DSpace/DSpace/tree/master/dspace-spring-rest
HATEOAS, HAL, & ALPS, oh my!
HATEOAS = Hypertext As The Engine Of Application State
In each response, include “links” to available next requests.
Results in better decoupling, as API is self-describing.
Formats: JSON*
Hypermedia as the Engine of Application
State - HATEAOS
curl "https://dspace7.4science.cloud/dspace-spring-rest/api"
• Response Properties
– Often pagination details
• Links
– What you can do next
• Embedded Resources
– List of objects which may contain
• Properties
• Links
Response Properties
Links: All endpoints are available
from the Entry Point
Communities Endpoint Response
Communities
endpoint
Pagination
properties
Links - A generic approach to
paginated results
Pagination
https://github.com/DSpace/Rest7Contract#pagination
• https://github.com/DSpace/Rest7Contract
– Explore the list of endpoints
• Implemented
• Unimplemented
• Under discussion
– Use GitHub pull requests to suggest
changes
The future of REST API Documentation
PR#1915
Exercise 1: Explore HAL Browser
https://jwt.io/
eid → EPerson uuid
sg → Special group
exp → Expiration
time
Why Authenticate?
http://bit.ly/dspace7-rest
Limitations of HAL AuthN
https://www.getpostman.com/downloads/
Postman - A tool for sending REST
requests
• Postman is a tool for interacting with
various REST services
– Even ones without a HAL Browser
• Using a web browser, it is difficult to
construct complex requests
Postman
Collections, Tabs, Workspace and Environments help you
organize and re-use requests
Collections, Tabs, Workspace and Environments help you
organize and re-use requests
Collections, Tabs, Workspace and Environments help you
organize and re-use requests
Select the right
HTTP Method
Request Area
Endpoint URL (can contains
variable from the Env)
http://bit.ly/dspace7-rest
Postman - Authenticating
as a User
AuthN Status in Postman
(no AuthN token)
authenticated: false
Authenticating in Postman
POST x-www-form-urlencoded
User credentials
Authentication Token
AuthN Status in Postman
(passing Bearer token)
Authentication Token retrieved
from the login endpoint
authenticated: true
Let’s Attempt to change data
http://bit.ly/dspace7-rest
How to deal with PATCH
http://bit.ly/dspace7-rest
Managing Postman
org.dspace.app.rest.repository.EPersonRestRepository
org.dspace.app.rest.model.EPersonRest
org.dspace.app.rest.model.hateoas.EPersonResource
DSpace 7 UI demo
https://dspace7-demo.atmire.com/
(uses the REST API demo as backend)
Slides available at
https://tinyurl.com/or2019-dspace7-advanced
Sl