Skip to content

Commit

Permalink
Merge pull request #40 from AtB-AS/master
Browse files Browse the repository at this point in the history
  • Loading branch information
cbrevik authored Aug 5, 2020
2 parents e11d998 + 811888d commit a6e7e5b
Show file tree
Hide file tree
Showing 27 changed files with 8,201 additions and 2,178 deletions.
5 changes: 5 additions & 0 deletions .graphqlconfig.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include: 'src/**/*.ts'
extensions:
endpoints:
Entur:
url: https://api.entur.io/journey-planner/v2/graphql
14 changes: 14 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,17 @@ API endpoints live in `api/`.

The current implementation uses [@entur/sdk](https://github.com/entur/sdk) as an
abstraction on top of Entur's GraphQL endpoints.

## GraphQL Code Generation

For endpoints that uses GraphQL directly we generate types and code using
`graphql-code-gen`. If the queries, scheme, operations or fragments change,
generate the code using scripts:

```
npm run gql-gen
```

This will make a TypeScript representation of the `.graphql` file in the same
location but with `.graphql-gen.ts` extension. You can use these directly as
queries.
33 changes: 33 additions & 0 deletions codegen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
overwrite: true
schema: 'https://api.entur.io/journey-planner/v2/graphql'
documents: ./src/**/*.graphql
generates:
src/graphql/types.ts:
config:
maybeValue: T
skipTypename: true
exportFragmentSpreadSubTypes: true
preResolveTypes: true
plugins:
- typescript
src/:
preset: near-operation-file
presetConfig:
extension: .graphql-gen.ts
baseTypesPath: graphql/types.ts
config:
withHooks: false
withComponent: false
withHOC: false
withResultType: false
skipTypename: true
# This causes some types to be wrong (e.g. in departure query dates are any type)
# but it makes using the types waay easier. Necessary evil in my mind.
preResolveTypes: true
exportFragmentSpreadSubTypes: true
# Looks like almost all types in the GraphQL server is optional but actually are set. The Maybe combinator
# is a pain to work with when traversing the types.
maybeValue: T
plugins:
- 'typescript-operations'
- 'typescript-react-apollo'
6,961 changes: 5,138 additions & 1,823 deletions package-lock.json

Large diffs are not rendered by default.

56 changes: 34 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,67 @@
"start": "node dist/index.js",
"start:dev": "ts-node --files ./src/index.ts",
"start:watch": "nodemon",
"test": "jest"
"test": "jest",
"gql-gen": "graphql-codegen --config codegen.yml"
},
"keywords": [],
"author": "",
"license": "EUPL-1.2",
"devDependencies": {
"@graphql-codegen/cli": "1.17.4",
"@graphql-codegen/near-operation-file-preset": "^1.17.4",
"@graphql-codegen/typescript": "1.17.4",
"@graphql-codegen/typescript-operations": "^1.17.4",
"@graphql-codegen/typescript-react-apollo": "^1.17.4",
"@types/hapi__inert": "^5.2.0",
"@types/hapi__vision": "^5.5.1",
"@types/jest": "^24.9.1",
"@types/jest": "^26.0.5",
"@types/lodash.sortby": "^4.7.6",
"@types/logfmt": "^1.2.1",
"@types/lz-string": "^1.3.34",
"@types/node": "^13.13.9",
"@types/node": "^14.0.24",
"@types/node-fetch": "^2.5.7",
"@types/uuid": "^7.0.4",
"jest": "^25.5.4",
"@types/uuid": "^8.0.0",
"copyfiles": "^2.3.0",
"jest": "^26.1.0",
"nodemon": "^2.0.4",
"prettier": "^1.19.1",
"ts-jest": "^25.5.1",
"ts-node": "^8.10.1",
"typescript": "^3.9.3"
"prettier": "^2.0.5",
"ts-jest": "^26.1.3",
"ts-node": "^8.10.2",
"typescript": "^3.9.7"
},
"dependencies": {
"@badrap/result": "^0.2.6",
"@entur/sdk": "^1.5.2",
"@google-cloud/pubsub": "^1.7.3",
"@google-cloud/trace-agent": "^4.2.5",
"@entur/sdk": "^1.7.2",
"@google-cloud/pubsub": "^2.3.0",
"@google-cloud/trace-agent": "^5.1.0",
"@hapi/boom": "^9.1.0",
"@hapi/hapi": "^19.1.1",
"@hapi/hapi": "^19.2.0",
"@hapi/inert": "^6.0.1",
"@hapi/vision": "^6.0.0",
"@opencensus/core": "0.0.20",
"@opencensus/exporter-stackdriver": "0.0.20",
"@opencensus/core": "0.0.22",
"@opencensus/exporter-stackdriver": "0.0.22",
"@types/continuation-local-storage": "^3.2.2",
"@types/hapi__hapi": "^19.0.3",
"agentkeepalive": "^4.1.2",
"date-fns": "^2.14.0",
"google-auth-library": "^5.10.1",
"@types/hapi__hapi": "^19.0.4",
"agentkeepalive": "^4.1.3",
"apollo-cache-inmemory": "^1.6.6",
"apollo-client": "^2.6.10",
"apollo-link-http": "^1.5.17",
"date-fns": "^2.15.0",
"google-auth-library": "^6.0.5",
"graphql": "^15.3.0",
"graphql-tag": "^2.10.4",
"hapi-api-version": "^2.3.1",
"hapi-pulse": "^3.0.0",
"hapi-swagger": "^12.1.3",
"hapi-swagger": "^13.0.2",
"haversine-distance": "^1.2.1",
"lodash.sortby": "^4.7.0",
"logfmt": "^1.3.2",
"lz-string": "^1.4.4",
"node-fetch": "^2.6.0",
"p-limit": "^2.3.0",
"p-limit": "^3.0.2",
"p-throttle": "^3.1.0",
"uuid": "^7.0.3"
"uuid": "^8.2.0"
},
"nodemonConfig": {
"ignore": [
Expand Down
6 changes: 6 additions & 0 deletions src/api/__test__/stops.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ const svc: jest.Mocked<IStopsService> = {
Result.ok(Promise.resolve([]))
),
getDepartures: jest.fn((...args: any): any => Result.ok(Promise.resolve([]))),
getDeparturesPaging: jest.fn((...args: any): any =>
Result.ok(Promise.resolve([]))
),
getDepartureRealtime: jest.fn((...args: any): any =>
Result.ok(Promise.resolve([]))
),
getNearestPlaces: jest.fn((...args: any): any =>
Result.ok(Promise.resolve([]))
),
Expand Down
46 changes: 0 additions & 46 deletions src/api/agent/index.ts

This file was deleted.

16 changes: 0 additions & 16 deletions src/api/agent/schema.ts

This file was deleted.

37 changes: 35 additions & 2 deletions src/api/stops/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
getDeparturesBetweenStopPlacesRequest,
getStopPlacesByNameRequest,
getNearestDeparturesRequest,
getDeparturesRequest
getDeparturesRequest,
getDepartureRealtime,
getDeparturesPagingRequest
} from './schema';
import {
StopPlaceQuery,
Expand All @@ -24,7 +26,9 @@ import {
StopPlaceByNameQuery,
NearestDeparturesQuery,
FeatureLocation,
DeparturesFromLocationQuery
DeparturesFromLocationQuery,
DepartureRealtimeQuery,
DeparturesFromLocationPagingQuery
} from '../../service/types';

export default (server: Hapi.Server) => (service: IStopsService) => {
Expand Down Expand Up @@ -190,4 +194,33 @@ export default (server: Hapi.Server) => (service: IStopsService) => {
return (await service.getDepartures(locaton, query)).unwrap();
}
});
server.route({
method: 'POST',
path: '/bff/v1/departures-from-location-paging',
options: {
tags: ['api', 'stops', 'departures'],
validate: getDeparturesPagingRequest,
description: 'Get departures from feature location'
},
handler: async (request, h) => {
const locaton = (request.payload as unknown) as FeatureLocation;
const query = (request.query as unknown) as DeparturesFromLocationPagingQuery;

return (await service.getDeparturesPaging(locaton, query)).unwrap();
}
});
server.route({
method: 'GET',
path: '/bff/v1/departures-realtime',
options: {
tags: ['api', 'stops', 'departures', 'realtime'],
validate: getDepartureRealtime,
description:
'Get updated realtime information of all lines and quays passed as data'
},
handler: async (request, h) => {
const query = (request.query as unknown) as DepartureRealtimeQuery;
return (await service.getDepartureRealtime(query)).unwrap();
}
});
};
31 changes: 31 additions & 0 deletions src/api/stops/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const getStopPlaceDeparturesRequest = {
includeNonBoarding: Joi.bool()
})
};

export const getDeparturesRequest = {
payload: Joi.object({
layer: Joi.string(),
Expand All @@ -40,6 +41,36 @@ export const getDeparturesRequest = {
walkSpeed: Joi.number().default(1.3)
})
};

export const getDeparturesPagingRequest = {
payload: Joi.object({
layer: Joi.string(),
id: Joi.string(),
coordinates: Joi.object({ longitude: Joi.number(), latitude: Joi.number() })
}).options({ allowUnknown: true }),

query: Joi.object({
limit: Joi.number().default(5),
startTime: Joi.date(),

// Paging
pageSize: Joi.number().default(10),
pageOffset: Joi.number().default(0),

// Deprecated fields
offset: Joi.number().default(ONE_MINUTE).description('Deprecated'),
walkSpeed: Joi.number().default(1.3).description('Deprecated')
})
};

export const getDepartureRealtime = {
query: Joi.object({
quayIds: Joi.array().items(Joi.string()).default([]),
startTime: Joi.date(),
limit: Joi.number().default(5)
})
};

export const getDeparturesFromQuayRequest = getStopPlaceDeparturesRequest;

export const getNearestDeparturesRequest = {
Expand Down
30 changes: 30 additions & 0 deletions src/graphql/graphql-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import ApolloClient, { DefaultOptions } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';

const link = new HttpLink({
uri: 'https://api.entur.io/journey-planner/v2/graphql',

// node-fetch uses a different signature than the browser implemented fetch
// But we use node-fetch's agent option in other parts of the project.
// The functionallity overlaps so this works as expected.
fetch: (fetch as unknown) as WindowOrWorkerGlobalScope['fetch']
});

const defaultOptions: DefaultOptions = {
watchQuery: {
fetchPolicy: 'cache-and-network',
errorPolicy: 'ignore'
},
query: {
fetchPolicy: 'network-only',
errorPolicy: 'all'
}
};

export default new ApolloClient({
link,
cache: new InMemoryCache(),
defaultOptions
});
Loading

0 comments on commit a6e7e5b

Please sign in to comment.