
Содержание статьи
Томас Рейнеке
Вы ищете быстрое начало игры с IBMs Cloud? Как насчет того, чтобы воспользоваться этой возможностью и соединить ее с некоторыми из последних и лучших технологий для Web VueJS, FeathersJS и GraphQL? Тогда это обязательное для вас прочтение, чтобы взлететь менее чем через час.

Что мы сделаем:
- Обзор программы
- создать новый репозиторий git на GitHub
- инициализировать внешнюю программу на основе Vue CLI
- инициализировать серверную программу на основе FeathersJS CLI
- добавить возможности GraphQL к серверной части
- протестируйте GraphQL API и опубликуйте/подпишитесь
- добавить зависимости к существующей внешней программе
- создать простой SPA, вызывающий серверную часть GraphQL
- развертывание в облаке IBM
Обзор программы

Создайте свежий репозиторий git на GitHub
Если у вас еще нет аккаунта GitHub, перейдите на github.com и создайте его. Создайте себе новый репозиторий под названием «VueAndIBMsCloud» (или любое другое название). Предполагая, что вы хорошо умеете пользоваться консолью, воспользуйтесь следующим кодом, чтобы создать свой первый коммит проекта:
mkdir VueAndIBMsCloud
cd VueAndIBMsCloud
echo "# VueAndIBMsCloud" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin
git push -u origin master
Инициализируйте внешнюю программу на основе Vue CLI
Если вам нужна дополнительная информация об установке Vue CLI, прочтите эту статью и вернитесь.
Установка — Vue.js
Vue.js – прогрессивная платформа JavaScript
vuejs.org
Используйте vue-cli для инициализации «интерфейсного» проекта на основе прогрессивной веб-программы (PWA):
npm install -g vue-cli
vue init pwa frontend
? Project name frontend
? Project short name: fewer than 12 characters to not be truncated on homescreens (default: same as name)
? Project description A Vue.js project
? Author thomasreinecke <thomas.reinecke@de.ibm.com>
? Vue build runtime
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Setup unit tests with Karma + Mocha? No
? Setup e2e tests with Nightwatch? No
Теперь скомпилируйте проект и запустите его в первый раз (вместо npm я рекомендую использовать yarn):
cd frontend
yarn
yarn dev
Ваша интерфейсная программа работает по адресу http://localhost:8080

Добро пожаловать, вы только что создали внешнюю программу на основе VueJs.
Инициализация серверной программы на основе feathersJS CLI

Используйте FeathersJS CLI для инициализации серверного проекта. Если вам нужна дополнительная информация о FeatherJS CLI, воспользуйтесь этой ссылкой и вернитесь:
feathersjs/cli
cli — интерфейс командной строки для создания программ Feathers
github.com
npm install -g @feathersjs/cli
mkdir backend
cd backend
feathers generate app
? Project name backend
? Description
? What folder should the source files live in? src
? Which package manager are you using (has to be installed globally)? Yarn
? What type of API are you making? REST, Realtime via Socket.io
yarn start
Ваша серверная программа работает по адресу http://localhost:3030/
Добавьте возможности GraphQL к серверной части
Откройте код Visual Studio (или желаемый IDE) > Откройте… > наведите его на fстаршие VueAndIBMОблако.
Откройте backend/src/index.html и замените его следующим кодом:
/* eslint-disable no-console */
const logger = require('winston');
const app = require('./app');
const port = app.get('port');
const createSubscriptionServer = app.get('createSubscriptionServer');
// create subscription server and associate it to the server
const server = app.listen(port, () => createSubscriptionServer(server));
process.on('unhandledRejection', (reason, p) =>
logger.error('Unhandled Rejection at: Promise ', p, reason)
);
server.on('listening', () =>
logger.info('Feathers application started on
app.get('host'), port)
);
В backend/package.jsonдобавьте следующие дополнительные зависимости для GraphQL:
"express-session": "1.15.6",
"graphql": "0.12.3",
"graphql-subscriptions": "0.5.6",
"graphql-tools": "2.18.0",
"subscriptions-transport-ws": "0.9.5",
"apollo-server-express": "1.3.2",
Бежать»пряжа” в командной строке, чтобы перетащить дополнительные библиотеки в ваш серверный проект. Теперь мы готовы создать службу Graphql с помощью дополнительного CLI:
feathers generate service
? What kind of service is it? A custom service
? What is the name of the service? graphql
? Which path should the service be registered on? /graphql
Вы поймете, что создан новый каталог: services/graphql.
Мы собираемся создать службу GraphQL несколько иначе, чем шаблон службы featherJS. Удалите graphql.hooks.js и graphql.class.js.
rm services/graphql/graphql.hooks.js
rm services/graphql/graphql.class.js
обновление services/graphql/graphql.service.js с таким кодом:
const { graphqlExpress, graphiqlExpress } = require('apollo-server-express');
const { execute, subscribe } = require('graphql');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const { makeExecutableSchema } = require('graphql-tools');
const TypeDefinitions = require('./graphql.typeDefs');
const Resolvers = require('./graphql.resolvers');
module.exports = function () {
const app = this;
const port = app.get('port');
const schema = makeExecutableSchema({
typeDefs: TypeDefinitions,
resolvers: Resolvers.call(app)
});
// provide endpoint to graphql for the apollo graphql client lib
app.use('/graphql', graphqlExpress((req) => {
return {
schema,
context: {}
};
}));
// provide endpoint to graphiql : the API explorer module
app.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql',
subscriptionsEndpoint: `ws://localhost:${port}/subscriptions`
}));
// define the API server here
app.set('createSubscriptionServer', function
createSubscriptionServer(server) {
return new SubscriptionServer({
execute, subscribe, schema,
onConnect: () => { console.log('Client Connected'); },
onDisconnect: () => { console.log('Client Disconnected'); }
},
{
server, path: '/subscriptions',
});
});
};
Теперь создайте GraphQL typedef и резольверы: создайте два новых файла под службы/graphql: graphql.typeDefs.js и graphql.resolvers.js и добавьте к нему такой код:
graphql.resolvers.js
const { PubSub } = require('graphql-subscriptions');
const pubsub = new PubSub();
const ITEM_ADDED = 'ITEM_ADDED';
module.exports = function () {
return {
Query: {
Welcome (root, { id }, context) {
return 'Welcome to VueAndIBMsCLoud example';
},
Items (root, { id }, context) {
return [
{
id: 1,
title: 'Item 1',
status: 'open',
created_at: new Date()
},
{
id: 2,
title: 'Item 2',
status: 'closed',
created_at: new Date()
}
];
}
},
Mutation: {
addItem(root, { id, title, status }, context) {
const item = {
id,
title,
status,
created_at: new Date()
};
pubsub.publish(ITEM_ADDED, { itemAdded: item });
return item;
},
},
Subscription: {
itemAdded: {
subscribe: () => pubsub.asyncIterator(ITEM_ADDED),
}
}
};
};
graphql.typeDefs.js
const typeDefinitions = `
type Item {
id: ID!
title: String
status: String
created_at: String
}
type Query {
Welcome: String,
Items: [Item]
}
type Mutation {
addItem(id: ID!, title: String!, status: String): Item
}
type Subscription {
itemAdded: Item
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
`;
module.exports = typeDefinitions;
Почти там. Давайте добавим начальный сценарий package.json в раздел «сценарии»:
"dev": "NODE_ENV=development node src/",
А теперь запустите yarn dev. Вы должны увидеть следующее сообщение:
информация: приложение Feathers запущено на http://localhost:3030
Протестируйте GraphQL API и опубликуйте/подпишитесь
Попробуйте graphiQL как модуль исследователя API и запустите первый тест следующим образом:

Добро пожаловать, вы включили GraphQL API в свой проект!
Теперь давайте проверим более сложную выборку данных:

А теперь тестируем подписку. Откройте graphiql во втором окне браузера и настройте подписку таким образом и нажмите кнопку «воспроизвести»:

Теперь вернемся к первому окну браузера graphiql, введите следующую мутацию, которая позволит вам добавить элемент в массив Items. Поскольку мы настроили публикацию/подписку, мы ожидаем, что изменения в массиве Items будут переданы всем подписчикам:

Разместите оба окна браузера рядом с другом и нажмите «Воспроизвести» в первом окне. Вы поймете, что внутренний сервер перенесет изменение данных в второе графическое окно:

Как это круто? Добро пожаловать, вы также настроили публикацию/подписку на основе graphiql в вашем проекте.
Добавьте зависимости к интерфейсной программе
В интерфейс/package.jsonдобавьте следующие дополнительные зависимости, чтобы включить поддержку Graphql, ApolloJS и подписки (через Websockets):
"dependencies": {
"apollo-cache-inmemory": "1.1.5",
"apollo-client": "2.2.0",
"apollo-link": "1.0.7",
"apollo-link-http": "1.3.2",
"apollo-link-ws": "1.0.4",
"apollo-utilities": "1.0.4",
"graphql": "0.12.3",
"graphql-tag": "2.6.1",
"subscriptions-transport-ws": "0.9.5",
"vue": "^2.5.2",
"vue-apollo": "3.0.0-alpha.3",
"vue-router": "^3.0.1"
}
Бежать»пряжа” чтобы перетащить зависимости в ваш внешний проект.
cd frontend
yarn
Редактировать интерфейс/main.js и замените код таким:
import Vue from 'vue'
import App from './App'
import router from './router'
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { split } from 'apollo-link'
import { WebSocketLink } from 'apollo-link-ws'
import { getMainDefinition } from 'apollo-utilities'
import VueApollo from 'vue-apollo'
// add unified ressource identifiers for Dev and Prod (IBM Cloud)
const uris = {
dev: 'localhost:3030',
prod: 'VueAndIBMsCloud.mybluemix.net'
}
// setup httpLink depending on environment
const httpLink = new HttpLink({
uri: (window.location.hostname === 'localhost') ? ` : `
})
// setup web socket link depending on environment
const wsLink = new WebSocketLink({
uri: (window.location.hostname === 'localhost') ? `ws://${uris.dev}/subscriptions` : `wss://${uris.prod}/subscriptions`,
options: {
reconnect: true
}
})
const link = split(
({ query }) => {
const { kind, operation } = getMainDefinition(query)
return kind === 'OperationDefinition' && operation === 'subscription'
},
wsLink,
httpLink
)
// define the apolloClient
const apolloClient = new ApolloClient({
link,
cache: new InMemoryCache(),
connectToDevTools: true
})
Vue.use(VueApollo)
const apolloProvider = new VueApollo({
defaultClient: apolloClient
})
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
apolloProvider,
router,
render: h => h(App)
})
Это подготовит вашу внешнюю программу к использованию ApolloClient как библиотеки для предоставления поддержки запросов, мутаций и подписки GraphQL. на uris объект, заменить VueAndIBMsCloud.mybluemix.net с целью продуктивного развертывания серверной программы.
Добавьте пользовательский интерфейс, вызывающий серверную часть GraphQL
В исходных кодах интерфейса откройте src/App.vue и замените его следующим кодом:
<template>
<div id="app">
<h1>{{ welcome }}</h1>
<ul>
<li v-for="(item) of items" v-bind:key="item.id">{{item.title + ' - ' + item.status}}</li>
</ul>
</div>
</template>
<script>
import gql from 'graphql-tag'
export default {
name: 'app',
data () {
return {
welcome: '',
items: []
}
},
mounted () {
this.$apollo.query({
query: gql`query {
Welcome
Items {
id
title
status
}
}`
}).then(({data}) => {
this.welcome = data.Welcome
this.items = data.Items
}).catch((error) => {
console.error(error)
})
},
}
</script>
<style>
body {
margin: 50px;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
main {
text-align: center;
margin-top: 40px;
}
header {
margin: 0;
height: 56px;
padding: 0 16px 0 24px;
background-color: #35495E;
color: #ffffff;
}
header span {
display: block;
position: relative;
font-size: 20px;
line-height: 1;
letter-spacing: .02em;
font-weight: 400;
box-sizing: border-box;
padding-top: 16px;
}
</style>
Сохранить и запустить разработка пряжи чтобы начать его. Теперь вы должны увидеть новую целевую страницу вашего внешнего приложения (которая еще не выглядит слишком увлекательной, но это первый раз, когда мы видим данные из вашей серверной части graphQL в вашем внешнем интерфейсе — разве это не круто?)

Теперь, поскольку у нас есть интеграция e2e между нашим интерфейсом и серверной частью graphQL, переместим его в облако IBM и запустим там.
Подготовка IBM Cloud к развертыванию
Теперь вы должны увидеть это:
API endpoint: <your endpoint> (<API version>)
Region: <your region>
User: <your username>
Account: <your account>
Resource group: default
Org: <your org>
Space: <your space>
Теперь вы установили область развертывания для ваших двух программ.
Развертывание серверной части для Bluemix
В серверном проекте создайте новый файл manifest.yml и введите в него содержимое:
applications:
- path: .
memory: 1024M
instances: 1
domain: eu-de.mybluemix.net
name: vueAndIbmsCloud-api
host: vueAndIbmsCloud-api
disk_quota: 1024M
Добавьте такой сценарий развертывания в package.json в раздел «сценарии»:
"deploy": "bx cf push vueAndIbmsCloud-api"
(Вы должны изменить название программы, чтобы сделать его уникальным, например, добавьте определенный индекс по своему выбору в manifest.yml и package.json.)
Установите BlueMix CLI
https://console.bluemix.net/docs/cli/index.html
https://developer.ibm.com/courses/labs/1-install-bluemix-command-line-interface-cli-dwc020/
бежать пряжа развернутьи это развернет вашу серверную программу в IBM Cloud.
Развертывание Frontend для Bluemix
Мы разворачиваем внешнюю программу на основе сервера nginx, который обеспечивает лучшую производительность (по времени отклика и пропускной способности), чем сервер узла.
В зависимости от того, какое название вы выбрали как цель развертывания серверной части, давайте убедимся, что оно правильно отображено в frontend/src/main.js. В uris замените ‘vueandibmscloud-api.eu-de.mybluemix.net’ на URL, где находится ваш внутренний сервер. Вы можете проверить URL-адрес в консоли Bluemix > щелкните приложение > просмотрите URL-адрес приложения.
В корневой папке внешнего приложения создайте файл manifest.yml и добавьте следующее содержимое:
applications:
- path: .
memory: 1024M
instances: 1
domain: mybluemix.net
name: vueAndIbmsCloud
host: vueAndIbmsCloud
disk_quota: 1024M
buildpack: staticfile_buildpack
Добавьте следующий сценарий развертывания в package.json в раздел «сценарии»:
"deploy": "npm run build; cp manifest.yml dist/manifest.yml; cd dist; bx cf push vueAndIbmsCloud"
(Вы должны изменить название программы, чтобы сделать его уникальным, например, добавьте определенный индекс по своему выбору в manifest.yml и package.json.)
бежать пряжа развернутьи это развернет вашу внешнюю программу в IBM Cloud.
Поздравляем:) Теперь вы можете использовать свою внешнюю программу в IBM Cloud.
Найдите источники на GitHub: