Presentation

Download as pdf or txt
Download as pdf or txt
You are on page 1of 156

Getting Started with

DSpace 7:
Advanced Training

Andrea Bollini, 4Science


Art Lowel, Atmire
Tim Donohue, DuraSpace
Workshop Schedule

❖ DSpace 7 UI deep dive (Angular)


❖ Customizing UI (beyond branding)
❖ DSpace 7 REST API deep dive
❖ Contributing back to DSpace
Hands-on Prerequisites
Instructions on
https://tinyurl.com/or2019-dspace7-wiki
What is Angular?
How does it work?
DSpace + Angular Back End

Architecture
Front End
Web Browser 1 Initial Request

2 Return first page, JS Database

3 Request data via REST


Assetstore

4 Return JSON

HTML logo: https://freeiconshop.com/icon/html-icon-outline/


JSON logo: http://www.flaticon.com/free-icon/json-file_136443
DSpace + Angular Back End

Architecture
Front End
Web Browser 1 Initial Request

2 Return first page Database


Javascript e
e x t pag
n
e q uest
3 R

ge Assetstore
t pa
nex
urn
Ret
4

Via Angular Universal


Angular Universal

Goal: support server-side rendering for


Angular apps … using the same code
that's used by the client
★ Better perceived performance
○ First page always rendered on server
★ Search Engine Optimization
★ Support other clients lacking Javascript
https://universal.angular.io/
Try it out now!

DSpace 7 UI demo
https://dspace7-demo.atmire.com/
(uses the REST API demo as backend)

DSpace 7 REST API demo:


https://dspace7.4science.cloud/dspace-spring-rest/

Run locally via Docker:


https://dspace-labs.github.io/DSpace-Docker-Images/
Intro to Angular

https://angular.io/tutorial
Angular Concepts

❖ Node / NPM / Yarn


❖ TypeScript Language
❖ Main architectural elements:
➢ Components
➢ Templates
➢ Services
➢ Modules

https://angular.io/docs/ts/latest/
Building / Running Angular Apps

: Server side JS platform


: Node’s package manager
Pulls in dependencies / third-party tools from registry

: third-party Node package mgr


• Same config as NPM (package.json)
• 3-5 times faster than NPM
• OS collab between Facebook, Google, and Tilde
TypeScript Language

• Extension of ES6 (latest JavaScript)


• Adds types and annotations
– No more “var”
– Expandable / sharable (Typings registry)
• Examples:
private title: string; (String variable)
private myItem: Item; (Item variable)
private myParam: any; (any type)
TypeScript Language

• Compiles to regular JavaScript &


errors can be detected at compile time
• May look familiar to Java and .NET
developers
– Interfaces, Generics, Decorators, …
• Much better IDE integration than JS
https://www.typescriptlang.org/
TypeScript Example
1 import { Metadatum } from "./metadatum.model";
...
2 export abstract class DSpaceObject implements CacheableObject {
3 name: string;
4 metadata: Array<Metadatum>;
...
5 findMetadata(key: string, language?: string): string {
const metadatum = this.metadata
6 .find((metadatum: Metadatum) => {
return metadatum.key === key &&
(isEmpty(language) || metadatum.language === language)
});
7 return metadatum.value;
Angular Architecture Overview

“You write Angular applications by composing


HTML templates with Angularized markup,
writing component classes to manage those
templates, adding application logic in
services, and boxing components and
services in modules.”
https://angular.io/docs/ts/latest/guide/architecture.html
Angular: Main elements

❏ Templates: compose HTML

❏ Components: display data via templates

❏ Services: retrieve data for components

❏ Modules: package components &


services
Angular: Templates

• HTML-like (almost all HTML is valid)


• Load other Components via their
“selector” (i.e. HTML tag)
• Components also have their own
templates

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

❏ Templates: compose HTML

❏ Components: display data via templates

❏ Services: retrieve data for components

❏ Modules: package components &


services
Angular: Components

• The building blocks of an Angular app


• Allow you to create new HTML tags that
come with their own code and styling
• Consist of a ‘view’ and a ‘controller’ in
the traditional MVC sense
Everything’s a
Component
● Header and footer
components

● Thumbnail and file


list components

● Collection list
component

● Specific metadata
field components
(extend shared one)

● Entire page too!


Angular: Components
▪ Each part of a webpage is a Component:
▪ … ‘implements’ Interface(s), e.g. onInit, onDestroy
▪ … ‘extends’ another Component
▪ … has a selector (HTML-like tag)
e.g. <news> = NewsComponent
▪ … has a constructor (defines its inputs)
▪ … has a template (view) and/or methods
(actions)
Calling a Component
(from a template)
<div class="wrapper">
<ds-header></ds-header>

<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

❏ Templates: compose HTML

❏ Components: display data via templates

❏ Services: retrieve data for components

❏ Modules: package components &


services
Angular: Services
Reusable “chunks” of code should be Services
• Singletons (shared/used globally)

• Provide streams of data for components


this.restService.get('/items')

• Provide operations to add or modify data


this.cacheService.add(item)
Dependency Injection (DI)

Inject Services into Components that need them

// (1) Define ItemDataService class as injectable


@Injectable()
export class ItemDataService { … }

// (2) Then, inject ItemDataService as input to a Component class


export class MyComponent {
constructor(private items: ItemDataService) {}
}
Example Service Class
1 @Injectable()
2 export class DSpaceRESTv2Service {
3 constructor(public http: Http) {}

4 get(relativeURL: string, options?: RequestOptionsArgs): Observable<string> {


5 return this.http.get(new RESTURLCombiner(relativeURL).toString(),
options)
.map(res => res.json())
6 .catch(err => {
console.log('Error: ', err);
return Observable.throw(err);
});
}
Angular: Main elements

❏ Templates: compose HTML

❏ Components: display data via templates

❏ Services: retrieve data for components

❏ Modules: package components &


services
Angular: Modules

• Classes used to simply organize your application


into “blocks” of functionality

• Grouping of components and/or services.


Import other modules.

• Angular App itself is a Module


(/src/app/app.module.ts)
Angular: Main elements

❏ Templates: compose HTML

❏ Components: display data via templates

❏ Services: retrieve data for components

❏ Modules: package components &


services
+
The DSpace 7 UI

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

"scripts": { - “scripts” section contains all


the build scripts in the
...
project
"server": "node dist/server/index.js",
... - yarn run ${scriptname}
"start": "yarn run server",
- scripts can call each other
...
},
Creating your branch

• git remote add workshop


https://github.com/DSpace-Labs/dspace-angular-
workshops.git
• git fetch workshop
• git checkout or2019-advanced-start
• git checkout -b or2019-advanced
Yarn commands when switching
branch

• Ensure dependencies are up to date


– yarn run clean
– yarn install
• Restart the dev server
– yarn run watch
DataPackage and DataType
entities

Goal: Create custom item pages for the new


DataPackage and DataType entities
Step 1: DataPackage component

Create a Component for DataPackage pages


Creating the DataPackage
component
• Start from the PublicationComponent
– Go to src/app/+item-page/simple/item-types
– Copy the publication folder to data-package
– Rename the files within to data-package.*
– Remove the .spec.ts file
Creating the DataPackage
component
• in data-package.component.ts
– remove @rendersItemType(DEFAULT_ITEM_TYPE, …)

– change @rendersItemType('Publication', …)

to @rendersItemType('DataPackage', ItemViewMode.Full)

– Change the selector to ds-data-package


– Update the styleUrls and templateUrl
Creating the DataPackage
component
• in data-package.component.html
– Replace {{'publication.page.titleprefix' | translate}}

With Data Package:


– That way we’ll see when it’s being used
Creating the DataPackage
component
• In src/app/+item-page/item-page.module.ts
– Add the new component to the declarations and
entryComponents sections.
– All new components should be added to declarations
– entryComponents is only for components that need to
be switched on the fly
Creating the DataPackage
component
• Restart the server and go to
http://localhost:3000/items/datapackage
Tag: or2019-advanced-1

• To sync your branch with the solution run:


– git reset or2019-advanced-start --hard
– git clean -f -d
– git merge or2019-advanced-1
Step 2: Configure the DataPackage
template
• Goals

– Change which metadata fields are shown

– Show related DataFile entities


DataPackage metadata fields

• Fix the journal title


– It is in prism.publicationName instead of
journal.title
• Remove fields for issn, volume-title and
citations
• Replace the URI field with DOI:
dc.relation.isreferencedby
Turn the DOI in to a link
<ds-metadata-field-wrapper [label]="'DOI'"
*ngVar="item?.firstMetadataValue('dc.relation.isreferencedby') as
doi">

<a href="https://doi.org/{{doi}}" target="_blank">{{doi}}</a>

</ds-metadata-field-wrapper>
DataPackage relations

• Remove relations for projects, org units and


journals from both the HTML and the ts
• add a relation for isDataFileOfDataPackage
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

• the pipe() function allows us to run a number of


operations on observables.
• The output of each operation is the input for the
next.
• The output of pipe() is a new observable that will be
updated every time the source observable changes
DataPackage relations

• 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

• The async pipe will ensure the template updates


when the observable changes
<ds-related-items
[items]="dataFiles$ | async"
[label]="'Data Files'">
</ds-related-items>
Tag: or2019-advanced-2

• To sync your branch with the solution run:


– git reset or2019-advanced-start --hard
– git clean -f -d
– git merge or2019-advanced-2
Step 3: DataFile Component
• Goals

– Create the component

– Add a relation back to the DataPackage


The DataFile component

• Start from DataPackageComponent


– Copy its folder to data-file
– Rename the files within to data-file.*
The DataFile component

• in data-file.component.ts
– change @rendersItemType('DataPackage', …)

to @rendersItemType('DataFile', ItemViewMode.Full)

– Change the selector to ds-data-file


– Update the styleUrls and templateUrl
The DataFile component

• 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

• Restart the server and go to


http://localhost:3000/items/datafile1
Tag: or2019-advanced-3

• To sync your branch with the solution run:


– git reset or2019-advanced-start --hard
– git clean -f -d
– git merge or2019-advanced-3
Debugging

• You can debug using your IDE


– connect the node debugger to localhost:5858
• Or debug using the browser’s dev tools
– disable server side rendering during
development:
• edit (or create) the file
config/environment.dev.js
• set universal.preboot to false
Debugging in the browser

• Source maps ensure you can debug in


typescript in the browser.
– keep in mind that variables can have a
slightly different name on a breakpoint

• Useful Chrome shortcut:


– Fuzzy file search: cmd+O / ctrl+O
Browser Extensions: Augury

• 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

• See the current state of the store, and the


actions that lead to it

• Go forwards and backwards through the actions

• Dispatch custom actions


Learning more

• Learn about Angular, Universal, and


other related technologies on the wiki:
https://tinyurl.com/dspace7-tech-stack

• Questions? ask on Slack


#angular-ui on dspace-org.slack.com
Why a new REST API?
Why a new REST API?
Covers only a Not based on current
4.x - 6.x
subset of DSpace REST best practices
functionality or standards
No search
No submit / workflows
Limited admin operations
Limited write / delete
(4.x was read only)
Handcrafted in Jersey,
while most DSpace code uses
Spring technologies
Why a new REST API?
All features MUST Defined REST Contract.
7.x
be in REST API HATEOAS, ALPS,
(for Angular UI) HAL format

Bonus: better third-party


app integration!

Built using Spring technologies


(Spring Boot, MVC, HATEOAS)

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.

HAL Format = Hypertext Application Language (JSON or XML)


A standard format for making REST APIs browseable
(think HTML for machines). Open source HAL Browser available.

ALPS = Application Level Profile Semantics*


Describes the operations (actions) available for all REST endpoints.
(Machine-readable) metadata about how to interact with the API.

RESULT: A standards-based, browseable, self-describing REST API


REST Terminology
Stateless (no session) HTTP methods
GET (read), HEAD (read headers only)
POST (create)
Specifications
PUT (replace), PATCH (partial update)
• JSON web tokens (JWT)
DELETE (remove)
• Cross-Origin Resource Sharing
(CORS) Headers OPTIONS (verify access, e.g. via CORS)

HTTP Resources HTTP return codes


● URIs reference individual 2xx (Success)
resources or collections (of 3xx (Redirect)
resources)
4xx (Client error)
● /items/{uuid} and /items
5xx (Server error)

Formats: JSON*
Hypermedia as the Engine of Application
State - HATEAOS

HAL Format ALPS


Links are expressed in a Available methods, semantics of
standard/well-known way in the request and response objects
json response (it is also suitable for discoverable in a standard way
xml but DSpace7 will focus only on (/profile) and expressed in multiple
JSON) standards format (Alps JSON, JSON
Schema, XML, etc)

→ enable the interactive navigation → enable to expose only available


methods (i.e. GET on
→ abstract routing (URL can change resourcepolicies is disallowed)
without break the client)
→ document in a machine-readable
→ support documentation way the request and response
semantics
Interacting with the
REST API
The slides in this section were originally
designed by Terry Brady, errors are mine
Interacting with a REST API

You can use the command line…

curl "https://dspace7.4science.cloud/dspace-spring-rest/api"

But, there are better ways… using a


REST client
HAL Browser

• Development public instance (provided


by 4Science)
– https://dspace7.4science.it/dspace-spring-rest/

• Navigate to the link above to explore


Request + Headers
Response Headers

HTTP Status code


Response Body

RAW JSON Response

The HAL Browser will parse the key


elements:
_links
_embedded
Everything else
HAL Document
Response Object Components

• 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

Resource Collections are always paginated


→ pagination information are returned in a
consistent way across all the endpoints
→ pagination parameters are expected in the
same form in all the endpoints
→ common JAVA API to deal with page jump
and offset
Embedded Community Properties
Embedded Community Links
Right use of the HTTP Verbs:
collection
- POST Adds a new element to the
collection.

- GET Returns the first page of the


resources in the collection
Right use of the HTTP Verbs:
element
GET Returns a single entity.
HEAD Returns whether the item resource is
available.
PUT Replaces the state
PATCH Similar to PUT but partially updating
the resources state
DELETE Deletes the resource exposed.
ALPS will enable...
HTTP status codes - 2xx, 3xx

200 Ok - Normal success state


201 Created - Returned when a resource is created
204 No content - Returned when the operation succeed but no
content is available (i.e. hit the logo endpoint of a community
without logo
206 Partial Content - DSpace 7 provides range support for
bitstream download allowing streaming

302 Found - the PID endpoint redirect to the target resource


HTTP status codes - 4xx

400 Bad Request - if the request is invalid (not a json, etc.)


401 Unauthorized - if the request require a logged-in user
403 Forbidden - if the requester doesn't have enough privilege
to execute the request
404 Not found - if the requested resource doesn't exists
405 Method Not Allowed - if the requested verb is not
supported for the resource
422 Unprocessable Entity - if the request is semantically
invalid (i.e. attempt to add undefined metadata, deposit an
invalid workspace)
REST Maturity level

Image from: https://martinfowler.com/articles/richardsonMaturityModel.html


The REST contract

• 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

Exercise 1 - Exploring Endpoints in HAL


Browser

Short Link To Exercises


http://bit.ly/dspace7-rest
REST Authentication

• The existing DSpace authentication


methods will be supported
• The REST API returns an authentication
token
• This token is passed to subsequent
REST requests as a header
JWT Token

A JWT Token contains user data “signed”


by the Server so that they cannot be
modified

https://jwt.io/
eid → EPerson uuid

sg → Special group

exp → Expiration
time
Why Authenticate?

• View restricted items/bitstreams


• Create/Update/Delete Objects
– Submit items
• Perform admin operations*
• View restricted metadata (provenance)*

Note: some of these actions are not yet supported


A subset of these operations are
available in HAL
Exercise 2: Authenticating in HAL

Exercise 2 - Authentication in HAL


Browser
• For this workshop, we will use
password authentication

http://bit.ly/dspace7-rest
Limitations of HAL AuthN

• Special chars not handled correctly


(DS-4259)*
• Multiple AuthN providers are not supported
(DS-3814)
• Credentials only passed for GET operations
• File uploads not supported

* it will be merged in the next few days


Postman - A development client for
REST API’s

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)

Tabs allow access to more


settings (parameters, auth,
content-type, request body)
Response Panel

The full response is included. A


pretty formatter simplify the Status code, time and
understanding of the JSON structure size of the response
are also visible
Response Headers

Headers are listed in a dedicated tab


Browsing with Postman

• View all communities


– /api/core/communities
• Change page size
– /api/core/communities?size=5
• Change starting page
– /api/core/communities?size=5&page=2
Exercise 3: Browsing with Postman

Exercise 3 - Browsing with Postman

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

• The current REST API allows a user to


start a submission
• POST
– /api/submission/workspaceitems
– Body: {}
• The response will return an object with
an id
Retrieving the Item that was
created
• GET
– /api/submission/workspaceitems/[id]
• DELETE
– /api/submission/workspaceitems/[id]
• GET
– /api/submission/workspaceitems/[id]
The second GET request will fail
Exercise 4: Authenticating with
Postman
Exercise 4 - Authenticating with
Postman

http://bit.ly/dspace7-rest
How to deal with PATCH

JSON Patch specification RFC6902


Express change to a JSON Object in JSON
Array of Operations executed in an atomic
transaction
Each successful Patch operation will return a
HTTP 200 CODE with the new state of the
patched resource as body similar to what is
returned for a GET request.
How to deal with PATCH

ADD / REMOVE / REPLACE / MOVE


[
{ "op": "test", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
]

TEST & COPY (no plan to support them)


PATCH (More examples: https://goo.gl/G84oRQ)
[{
"op": "add",
"path": "/sections/traditionalpageone/dc.contributor.author/-",
"value": {"value": "Another, Author"}
}]
Exercise 5: Interact with the
submission
Exercise 5 - Interact with the
submission

http://bit.ly/dspace7-rest
Managing Postman

• Postman allows you to use variables


and scripts to manage credentials
• Environments allow you to switch
easily from one installation: test,
staging, prod (!) to another - can be
also used to switch between user
Tips on using postman
A look to the JAVA
backend
Spring technologies

Spring Bootstrap: pre-configured managed


Spring platform
Spring MVC: Front Controller, data binding,
error handling
Spring REST: MVC extension to easily
support Content-Negotiation, Response in
JSON format
Spring technologies

Spring HATEOAS: library to deal with HAL


Document (Resources, Resource, Links, Curie)
Spring Data REST: only for inspiration
(consistent design choices, HTTP error
handling, support classes, etc.)
Spring technologies

Spring Data REST Hal Browser: WebJar of


the HAL browser customized to work at best
with Spring Data REST
Spring REST Docs: Self contained
documentation with snippets from Integration
Tests
How URL are translated to JAVA
code
Where is my web.xml?

It is a spring boot application with web


support (MVC)
Controller → are the “new” Servlet
@RestController
What about the lovable spring xml files?

sorry now we use annotations :)

Component scanning enabled on


repository, converter, utils packages
@Component
@Service
Walkthrough the EPerson endpoint

org.dspace.app.rest.repository.EPersonRestRepository

• List EPersons → findAll


• Get EPerson → findOne
Rest Model Class

org.dspace.app.rest.model.EPersonRest

• POJO used as DTO between the REST


layer and the services.
• Clean and stable version of our data
model
• The converter class transcode the
DSpace-API objects in REST objects
Repository Class

• It is defined in the Repository design


pattern
• It implements the Data Access Layer in
DDD
• Close to the domain model, abstracting
access to a collection
Resource Class

org.dspace.app.rest.model.hateoas.EPersonResource

• Wrap the Domain Class inside an HAL


document
• Provide supports to add links
• Manage embedded objects
Integration Test
org.dspace.app.rest.EPersonRestRepositoryIT

Builder and Matcher helper classes to keep code


compact & cleanup the test database between
runs
One or more test for each repository methods
- Separate test for different scenarios
(exception, limit case, normal case)
- Multiple calls in the same test to cross check
the intent changes
@PreAuthorize
org.dspace.app.rest.security.EPersonRestPermissionEvaluatorPlugin

• Security checks isolated in dedicated


classes, more cohesive and reusable
• Pluggable implementations to approve
incoming requests
Walkthrough - Search Methods
https://goo.gl/NSju3q

Collection endpoints that allowing


filtering, search or precise lookup of
resources MUST provide a search link
listing all the available methods
• findByName
• findByEmail
Contributing Back
How can I help, technically?

Join Community Sprints (coming again soon)

Join DSpace 7 Working Group

➢ Next meeting: Thurs, June 20 at 14UTC

Join DSpace 7 Entities Working Group

➢ Next meeting, Tues, June 18 at 15UTC


More info at OR2019

★ DSpace 7 - Creating High Quality


Software: Update to Development
Practices (Developer Track)
○ Weds, 9:00am (Lecture Hall M)
○ Andrea Bollini, Terry Brady,
Giuseppe Digilio, Tim Donohue
How can I help, non-technically?

Join DSpace 7 Marketing Working Group!

➢ Marketing both DSpace 7 and DSpace (in


general). Thank them for t-shirts & buttons!

Join DSpace Community Advisory Team (DCAT)

➢ Repository Manager interest group


➢ Advises on community needs
Help by becoming a member!
DSpace is funded / developed / supported
by its community.

★ Become a member and influence product roadmap,


governance and member benefits.
★ Membership also funds coordination
(Tech Coordinator, Product Coordinator?)
Try it out now!

DSpace 7 UI demo
https://dspace7-demo.atmire.com/
(uses the REST API demo as backend)

DSpace 7 REST API demo:


https://dspace7.4science.cloud/dspace-spring-rest/

Run locally via Docker:


https://dspace-labs.github.io/DSpace-Docker-Images/
Questions?

Slides available at
https://tinyurl.com/or2019-dspace7-advanced
Sl

You might also like