-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update examples to work with latest loopback versions #78
Update examples to work with latest loopback versions #78
Conversation
Can one of the admins verify this patch? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
services/account/test/unit/test.ts
Outdated
|
||
accCtrl.repository = new AccountRepository( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have a use for test.data.json
after removing it here?
@@ -10,4 +10,4 @@ | |||
"CHK99999999": "{\"id\":\"CHK99999999\",\"customerNumber\":\"0002444422\",\"balance\":100.89,\"branch\":\"Foster City\",\"type\":\"Checking\",\"avgBalance\":100.93,\"minimumBalance\":10}" | |||
} | |||
} | |||
} | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newline here
services/account/index.ts
Outdated
); | ||
super(options); | ||
|
||
const dataSource: juggler.DataSource = new DataSourceConstructor('local-fs', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make more sense to define datasource
elsewhere in its own file (for e.g. /datasources/mem.datasource.ts
), and only bind it in this file.
async deleteAccount(where) { | ||
return await this.repository.deleteAccount(JSON.parse(where)); | ||
} | ||
async updateAccount(where = '', data) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we setting where
to an empty string here?
return await this.repository.updateAll(data, JSON.parse(where)); | ||
} | ||
|
||
async deleteAccount(where = '{}') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto; why are we setting where
filter to an empty object?
@@ -0,0 +1,4 @@ | |||
import {Entity, model} from '@loopback/repository'; | |||
|
|||
@model(require('./accoun-definition.json')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
./accoun-definition.json
-> ``./account-definition.json`
import {Entity, model} from '@loopback/repository'; | ||
|
||
@model(require('./accoun-definition.json')) | ||
export class Account extends Entity {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newline here
@thinusn I have rebased and added 3 commits which aim to fix the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, just a few changes:
- needs to restore the original formatting of some files
- remove package-lock files
- fix missing newlines (GitHub's diff will show you where using the 🚫 emoji/symbol)
import { api } from '@loopback/rest'; | ||
import { def } from './AccountController.api'; | ||
import { AccountRepository } from '../repositories/account'; | ||
import { inject } from '@loopback/context'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our style guide in the loopback monorepo requires that there be no added spaces after the brackets and imports.
import {inject} from '@loopback/context';
I know that this is a different repository, but the existing code is also following that style, so we should leave it as-is. If you've got something auto-formatting it, then you should reconfigure it for that style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -2,11 +2,10 @@ import {Entity, model, ModelDefinition} from '@loopback/repository'; | |||
|
|||
@model(require('./account/model-definition')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still required now that the @model
decorator automatically generates metadata based on the constructor definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point. we can probably get rid of it!
@@ -1,3 +1,4 @@ | |||
// test/unit/account-controller.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary comment.
@@ -1,6 +1,6 @@ | |||
{ | |||
"ids": { | |||
"Account": 23 | |||
"Account": 5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably:
- make a one-time setup to generate this data file if it doesn't exist
- ignore it in .gitignore so that it can stop showing up in changes
(this is optional for this review)
services/account/tsconfig.json
Outdated
], | ||
"exclude": [ | ||
"node_modules/**", | ||
"packages/*/node_modules/**", | ||
"**/*.d.ts" | ||
] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing newline (it wasn't your fault, but since we're here... :) )
services/customer/package-lock.json
Outdated
@@ -0,0 +1,1893 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No package-lock.json
files, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thinusn Thank you for the contribution.
We recently upgraded to OpenAPI 3.0.0 and I left comments for the specs need to be upgraded.
But before upgrading anything, I want to confirm with team @strongloop/loopback-next is this example repo aimed on the API first approach? Or we can refactor the code to generate apis by decorators?
@@ -24,6 +24,26 @@ export const def = { | |||
}, | |||
}, | |||
}, | |||
'/accounts/{id}': { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The OpenAPI specifications are upgraded to 3.0.0, please update the path
spec accordingly, see document https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject
The corresponding 3.0.0 spec would be:
get: {
'x-operation-name': 'getAccount',
parameters: [
{
name: 'id',
in: 'path',
description: 'Model id',
required: true,
// please note the 3.0.0 organizes properties like `type`, `format` are under `schema`.
schema: {
type: 'string',
format: 'JSON',
}
},
],
responses: {
200: {
// please note 3.0.0 supports multiple content-types,
// change it to `*/*` or any working content-type
'*/*': {
// And 2.0 definitions are organized to components/schemas
schema: '#/components/schemas/Account',
},
},
},
},
},
My code may not work out-of-box, please double check it.
@@ -0,0 +1,34 @@ | |||
export const accountDefinition = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can decorate the model by
@model
Class Account {
@property('id') id:string,
// ...etc
}
If any controller method has argument with type Account
, then the OpenAPI schema
for Account
will be auto-generated.
{ | ||
name: 'filter', | ||
in: 'query', | ||
description: | ||
'The criteria used to narrow down the number of customers returned.', | ||
description: 'The criteria used to narrow down the number of customer returned.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The specifications here also need to be updated as OpenAPI 3.0.0.
@@ -7,14 +7,14 @@ | |||
"host": "localhost:3001", | |||
"basePath": "/", | |||
"paths": { | |||
"/accounts": { | |||
"/accounts/{id}": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be updated as openapi.json.
}, | ||
"deprecated":false | ||
} | ||
"swagger": "2.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be updated as OpenAPI 3.0.0 spec as well.
}, | ||
} | ||
}, | ||
definitions: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same ^ OpenAPI 3.0.0
}, | ||
"deprecated":false | ||
} | ||
"swagger": "2.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same ^ OpenAPI 3.0.0
/* tslint:disable:no-unused-variable */ | ||
import { | ||
DataSourceConstructor, | ||
juggler, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of doing this, would it not be better to do
import * as lbRepository from '@loopback/repository';
import * as lbBoot from '@loopback/boot';
and then the class would be defined as follows
export class AccountMicroservice extends lbBoot.BootMixin(lbRepository.RepositoryMixin(RestApplication)) {
That way we don't have to deal with the unused-variable
ts error, and the IDE's auto formatting removing these unused imports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While that removes the unused-variable
tslint error, it's good practice to import only what we need from those modules as it makes it clear what we use from them. This is the approach we take in loopback-next
and it'd be good to follow it here.
hey @thinusn are you still interested to work on this PR? |
@b-admike jup, I just need the time to sit down actually do it |
package.json
Outdated
@@ -39,9 +39,9 @@ | |||
"bluebird": "^3.5.0", | |||
"mocha": "^5.0.3", | |||
"ts-node": "^3.1.0", | |||
"typescript": "^2.6.1" | |||
"typescript": "^2.4.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for downgrading typescript?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope good catch will make it the same version as https://github.com/strongloop/loopback-next/blob/master/packages/build/package.json
@thinusn Excellent work. Thank you for committing in small increments and following our commit message guidelines! I'm going to review your latest commits, but so far so good (I've reviewed a bunch and haven't found anything that stands out). |
Account, Customer Transaction and Facade is now working again and up to date with latest lb versions . I made some changes to how the app starts all the services and general improvements / updates throughout. |
import {dataSource} from './swagger.datasource'; | ||
/* tslint:disable no-any */ | ||
export class AccountRepository { | ||
model: any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@b-admike How do we want to get the types into the Facade? I did not want to import them from eg. '../../../account/bla/bla' as we then have a direct coupling. For now I just made the types any, perhaps this example should also be a lerna project in the future, that way the facade can just import the types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for setting up Lerna-based monorepo in this repository. The sooner we can make that transition, the better.
@@ -0,0 +1,76 @@ | |||
export const accountDefinition = { | |||
swagger: '2.0', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loopback-connector-swagger
packages does not support openapi 3.0 :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too caught up on the purpose of facade
, but is it necessary for the package to be using loopback-connector-swagger
@strongloop/lb-next-dev ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing up what was in need of some dire upgrade! Here's a couple of high-level comments that may help you finish this PR quicker and easier:
- going over the README again to see if it's still accurate after the update
- users need to give explicit permission to execute shell scripts, we should do this for them in our scripts
- we should leverage lerna to resolve dependencies between folders if needed
- use automatic openapi spec generating decorators (like @get, @param, etc.)
- add properties to existing models and use the model class as types
- complete switching repositories over to extending from
DefaultCrudRepository
- make sure to include
dist
folders in.gitignore
I think the scope of this task only includes the first two points (README and shell script execution privilege) and the rest would be more appropriate for a refactor in a separate PR.
Please don't hesitate to ping us if you need help in getting this PR landed :)
options = Object.assign( | ||
{}, | ||
{ | ||
components: [RestComponent], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't support binding components via the constructor anymore.
Please bind the component through app.component(RestComponent)
instead.
Alternatively, the application could extend from RestApplication
instead, which already has RestComponent
and RestServer
registered.
}, | ||
components: { | ||
schemas: { | ||
Account: accountDefinition, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please create a spec for Account
here as well
} | ||
|
||
setupDataSources() { | ||
this.bind('dataSources.memory').to(dataSource); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't important, but we now have a sugar for this in RepositoryMixin
as this.dataSource(dataSource)
:)
}, | ||
components: { | ||
schemas: { | ||
Customer: customerDefinition, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
customerDefinition isn't a valid SchemaObject according to petstore.editor. It can't have key name
in it.
|
||
let custCtrl: CustomerController; | ||
|
||
// const testCust = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to delete these comments before merging
content: { | ||
'*/*': { | ||
schema: { | ||
$ref: '#/components/schemas/AccountFull', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean Account
?
transactionRepository: TransactionRepository; | ||
|
||
constructor() { | ||
this.accountRepository = new AccountRepository(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use dependency injections for these instead?
@@ -0,0 +1,25 @@ | |||
import {FacadeMicroservice} from './application'; | |||
import {RestServer, RestBindings} from '@loopback/rest'; | |||
import 'loopback-connector-swagger'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this line
@@ -0,0 +1,76 @@ | |||
export const accountDefinition = { | |||
swagger: '2.0', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too caught up on the purpose of facade
, but is it necessary for the package to be using loopback-connector-swagger
@strongloop/lb-next-dev ?
@thinusn Would you still be interested in doing further work on this PR? I personally think it is good to land on its own. Please let us know so that we could move further on ahead with this repository :) |
@shimks I think it is about time we get this pr merged, would rather do more in a future pr |
@thinusn I want to get the CI passing before we merge this PR and wanted to clean the PR up a bit to get it to pass. Could you grant me permission to make changes to the PR? |
@slnode test please |
Thanks @thinusn for your massive help in updating this hugely outdated repository :D |
Description
Updated the examples (accounts, customer, transactions & facade) to work with the latest versions of
@loopback/*
.The example now runs and builds with
I added tests for
customer
andtransaction
and updated the existing account tests. I also changed the example slightly to make the facade work. All tests for the examples are passing.Related issues
Checklist