Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
We are happy that you're here! 👋
So what is code.store? It all started with a simple idea: the complexity of the modern world is astonishing and is increasing every day, that's why we should be spending our time and energy on problems that are new and complex to solve and try and reuse everything else. So we decided to create a platform for companies and software engineers to reuse and share live, hosted code among projects and organizations. We also want to create a public marketplace where every developer and company could sell their API-first services on a subscription or pay-per-call rate-plan.
So, in short, code.store is a backend-as-a-service, a GraphQL schema-first platform where you can build, host, reuse, and bill your so that you could create some truly amazing products!
For the good of your company and the planet, we think that reusing code is very important!
Like many other great products, code.store is continuously evolving as we are striving to bring more features, improve the existing ones and make sure that the product is as stable as it could be. 🤞
That's why if you have ANY suggestions while using code.store, whether it be feature requests, suggestions on how to improve our documentation, or just some questions, we are here for you!
Create a feature request or chat with us in real-time in our community home here: .
A good to place to start would be to read about , and of course, our .
Enjoy the reading and don't hesitate to !
If you have nothing else to do, you can read this long piece of art about our vision of the future of the world. 🤦♀️
We created code.store because we believe the way software is being built today is not adapted to the pace of the modern world. We think that you should not spend time on problems that have been already solved in the past.
Software started with fully custom-built monoliths. Large mono-repository projects where teams coded absolutely everything. Then came frameworks and software editor solutions (Magento, Drupal, Wordpress, Salesforce, SAP...), providing vertical monoliths for common needs (CRM, e-commerce, ERP, DAM, PIM, ...). Usually, clients of software editor solutions end up overpaying for features they don't use (a client uses only 30% of features on average), and they still have an ever-growing budget for maintenance of a massive monolith.
Now is the time to build software in a new way: re-using small building blocks that solve a unique functional problem, like using lego bricks.
Modules, packages, DLLs, JARs, servlets, there has always been a desire for reusability, but there were always many barriers to reusability: technological stack, support & maintenance, integration, compatibility, and size of each component, the coupling between UX and back-end.
So why it would be different with code.store?
In the past years, the world of web-development saw several profound changes in the way we build software that makes out code.store idea reasonable:
Headless and decoupled approaches
With robust and stable frontend frameworks like Angular, React, and Vue, it is now easy to build genuinely decoupled applications. It is important because the strongest barrier to reusability is frontend and UX. With decoupling, we can focus on API reusability.
GraphQL
It offers a lot of flexibility to frontend developers. Previously, each time an application needed a product listing presented in a slightly different way, we would either have to load all the unnecessary data from a single REST endpoint or ask backend developers to provide a new "lighter" endpoint.
When independent developers, companies, or digital agencies build software for others, they usually bill the time they spent on it. It's therefore complicated to re-use components from one project to another, and almost impossible to share funding, specifically when you mix hosting and support. We wanted to change that paradigm by providing a new way for billing projects.
For each service on code.store, you may activate metered or monthly billing and sell them to your clients. We take care of retrieving funds and take a small cut of only 10%. The recurring revenues cover your initial development time, hosting resources, our platform, and the time you spent on the support and maintenance of your service.
Nowadays, « Every company is a tech company », but being a software editor is not easy. Initial technological stack, marketing, R&D investments, ROI roadmap management, indirect distribution are complex and inaccessible for most companies.
We bet that by providing a common platform and reducing the software to « bite » sized, running, live service, we’ll enable re-usability, sharing and ultimately, billing through direct sales or marketplace.
There are too many ways to create software today. We created code.store in a way that you can focus only on your code, while we take care of the rest (some of the features in the list are still in the roadmap, but we are working hard to deliver them to you as soon as possible):
containerization
database modelling and management
security
GDPR
code.store is a rather opinionated platform, which means we have made a certain number of choices for you to simplify the development. However, we want it to be a platform built by developers for developers, and we are open to suggestions and would be very happy to hear from you in our community chat !
PS: If you've read it all, please about us!
Oops!🙀 Our team is working hard to build a great web UI that will help manage your services online. Join us at our community home to find out more about it and when it is going to be released: https://spectrum.chat/code-store
We'll create a service where you can store, update and read data in your service.
Coming soon!
You want to reuse live, running, supported, and functional code. That means you accept that the module/service/lego brick you reuse might run somewhere and you do not care if it handles traffic and provides good SLAs.
Microservices are mainstream
You already do "microservices" without knowing it, when you implement external APIs on your projects like Google Maps, Stripe, or Facebook Connect. Call them nano/micro/macro/mini services, but your project is already the patchwork of small, isolated, and autonomous services glued together by your frontend application.
performance
continuous integration and deployment
automated tests
monitoring
24/7 support
instant re-use
👋 Take my hand, stranger. We'll go through code.store paradise.
The goal of this section is to get you up to speed real fast. We are going to learn how to install and use the command line tools of code.store, how to create an account, and write a basic service! Let's continue 🚀
Services, which project includes and deployed in one environment can communicate with each other.
To call GraphQL or REST API of another service on the same environment - make an HTTP request, where URL should build by next pattern: http://{SERVICE_NAME}-service Each service has an internal URL which available only per environment.
Let's imagine that we have service "example", which deployed to the development environment. This service can be accessed by another service on the development environment by next URL:
To provide an HTTP call to service install any HTTP client, for example axios using npm:
Import axios dependency in your code:
And execute request yo your service. In example below you can find simple HTTP request to [GET] /rest/hello route of example service:
The result of HTTP request execution will be available in the result object.
http://example-servicenpm i axiosimport axios from 'axios';const result = await axios.get('http://service-example/rest/hello');To help you with local development of you services you'll need a local Postgre database.
You know that we care about your time, so we created a local launcher for your services. But you also know that your services have a local database to store your objects. Let's setup a local Postgre database.
I love working with their simplest version: postgreapp. Go there and download it.
Launch the application. You have your local postgre database. You should see a small icon of postgre in your menu top bar.
Now you can go in any of your services folders and and edit codestore.yaml file. You should see something like that :
Change the database name, password, and username to the ones from
To test your connection, nothing more simple : execute in the root folder of your service cs dev command. You should see something like that :
code.store platform support middleware functions for REST endpoints. To avoid manual file creation allowed a command cs generate:middleware, which generate a template of middleware with handler method.
To generate middleware for your route just execute cs generate:middleware CLI command, select one of middleware type: request or response middleware type, specify name for your function and select route from the route list:
> cs generate:middleware
? Select position of middleware (Use arrow keys)
response
❯ request
? Enter name of your middleware: permissions
? Select route to apply (Use arrow keys)
File ./demo_app/src/rest-middlewares/permissions.middleware.ts has been generated.
After command execution will be generated file permissions.middleware.ts in src/rest-middlewares directory:
More information about handler method and his params can be found in section.
code.store platform support file based REST endpoints. To avoid manual file creation allowed a command cs generate:rest, which generate an empty route template with handler method.
To generate REST route just execute cs generate:rest CLI command, select one of HTTP methods: GET, POST, PUT, DELETE and specify a new route name
> cs generate:rest
? Select HTTP method (Use arrow keys)
❯ GET
POST
PUT
DELETE
? Select HTTP method GET
? Name of your REST endpoint helloAfter command execution will be generated file get.hello.ts in src/rest directory:
More information about handler method and his params can be found in section.
code.store platform makes it possible to generate most of the necessary entities for comfortable development.
At the beginning of the journey, when creating a service, it is possible to choose the language of your future service. code.store platform will generate default "hello world" application.
Generation happens cs generate CLI command. During development, it is possible to generate entities such as:
By default, each service has different variables, which depends on the environment. For example, database environments, which available on the development environment may differ from the staging environment, and so on... For more information about environments, see the Environments section. Depends on service language, environment variables can be accessed in different ways.
To access environment variables using TypeScript or JavaScript language use:
Below, you can find information about available environment variables which code.store platform set by default.
PROJECT_ID internal ID of the project on the code.store platform
ENVIRONMENT_ID name of the , where service deployed
SERVICE_ID internal ID of the service on the code.store platform
DATABASE_HOST connection host
DATABASE_PORT connection port
DATABASE_NAME name of the database
DATABASE_USERNAME name of the user which can access to services database
REDIS_HOST Redis connection host
REDIS_PORT Redis connection port
NODE_VERSION node version, which deployed service used
process.envserviceId: 145
localConfiguration:
database:
port: 5432
database: database
password: password
username: username
host: localhost
application:
port: 3000/**
* This handler was generated by code.store CLI.
*
* Visit our documentation to learn more about the support of REST APIs in our SDK:
* https://docs.code.store/getting-started/sdk/rest-apis
*
* You can also join our community at https://spectrum.chat/code-store if you have any
* questions which are not covered by the documentation.
*
*/
import { Handler } from 'codestore-utils';
const handler: Handler = async (event, context) => {
// your code goes here
return 'Hello, world!';
}
export default handler;/**
* This handler was generated by code.store CLI.
*
* Visit our documentation to learn more about the support of REST APIs in our SDK:
* https://docs.code.store/getting-started/sdk/rest-apis
*
* You can also join our community at https://spectrum.chat/code-store if you have any
* questions which are not covered by the documentation.
*
*/
import { Handler } from 'codestore-utils';
const handler: Handler = async (event, context) => {
// your code goes here
return 'Hello, world!';
}
export default handler;After command execution will be generated file get.hello.ts in src/rest directory:
More information about resolver method and his params can be found in GraphQL section.
> cs generate:resolver
? Select the type of resolver (Use arrow keys)
❯ query
mutation
? Enter the name of your resolver helloTo generate auth handler execute cs generate:resolver CLI command, select auth handler type:
After command execution will be generated file auth.handler.ts in src/resolvers directory:
You can specify your authentication strategy here. This handler works as an authentication middleware which will be called for all GraphQL queries/mutations marked with directive @auth.
In order to use that directive in your GraphQL schema, add a following directive declaration at the top of your GraphQL file:
Then use it in query/mutation declarations, for example:
Use context handler as a handler, which will be execute before each GraphQL resolver. To generate context handler execute cs generate:resolver CLI command, select context handler type:
After command execution will be generated file context.handler.ts in src/resolvers directory:
cs dev
2020-09-11T10:10:00.638Z [NPM] Installing dependencies
2020-09-11T10:10:05.359Z [TypeScript] Compiling typescript code
2020-09-11T10:10:13.745Z [GraphQL] Validating schema
2020-09-11T10:10:13.767Z [GraphQL] Validating queries and mutations
2020-09-11T10:10:17.168Z [INFO] Starting development server
2020-09-11T10:10:17.168Z [Bootstrap] Start bootstrapping the application
2020-09-11T10:10:17.168Z [Database] Connecting to database
2020-09-11T10:10:17.316Z [Database] Successfully connected
2020-09-11T10:10:17.441Z [Database] Migrations ran
2020-09-11T10:10:17.443Z [GqlLoader] Loaded queries: load
2020-09-11T10:10:17.462Z [Bootstrap] Graphql is available on: http://localhost:3000/graphql/**
* This resolver was generated by code.store CLI.
*
* Visit our documentation to learn more about writing custom resolvers for your GraphQL schema:
* https://docs.code.store/getting-started/quick-start/quick-start-with-cli
*
* You can also join our community at https://spectrum.chat/code-store if you have any
* questions which are not covered by the documentation.
*
*/
import { Resolver } from 'codestore-utils';
const resolver: Resolver = async (parent, args, context, info) => {
// Your code goes here.
// Example of how to initialize an Entity:
// const exampleEntity = context.db.connection.getRepository(exampleEntity);
// exampleEntity.find();
return 'Hello, World!';
}
export default resolver;> cs generate:handler
? Select the type of resolver (Use arrow keys)
❯ auth
context import { AuthHandler } from 'codestore-utils';
const authHandler: AuthHandler = async (context) => {
// your code goes here
return {};
};
export default authHandler;directive @auth on FIELD_DEFINITIONtype Query {
helloWorld: String! @auth
}> cs generate:handler
? Select the type of resolver (Use arrow keys)
auth
❯ context import { ContextHandler } from 'codestore-utils';
const contextHandler: ContextHandler = async (context) => ({
// your code goes here
});
export default contextHandler;The bigger your system grows and the more libs or packages you integrate into your project, the more likely you are to face such a problem as dependency hell.
As a solution, code.store platform suggests relying on a simple set of rules and requirements that govern how version numbers are assigned and incremented. There are many approaches to software versioning and their interfaces, the choice is always up to the developer.
When you create a new service, by default, it deployed into private and demo and it's version is 0.0.1
To find out which version is in use execute cs service:info CLI command and select the service. You will find which versions deployed on private and demo environments.
On example above on the private environment deployed service with 0.0.2 version and 0.0.1 on the demo.
If you already include service to project, you can execute cs project:service:info CLI command, select project and service to display.
On example above deployed on three environments deployed next versions:
To create a new version just push your changes using cs push CLI command. More information about pushing changes can be found in section. After pushing changes - a new version will be available on the private .
It's very important to increment service version after making changes to service. Actual service version is always available at package.json file.
After creating a new service version using cs push command - changes will be available only on the private .
demo - is the only place, where developed changes can be published. Changes from demo environment is available for including to the project or public .
To make a new version available - execute cs promote CLI command. This command will deploy changes from private to demo environment and makes a new version available for update/include into projects. Promoted version to demo environment is marks as LATEST
When you include a new service to the - version from demo will be deployed. This allows adhering to the concept of public release of new versions to avoid unexpected system behavior. More information about including services to projects can be found in section.
After including service to the project - it's deployed only to development . To move service version to another environment use cs project:service:promote CLI command. It allows you to move already deployed version to another environment.
For example, if your project includes some service - you can promote only already deployed service version to another environments.
To update project service to latest version execute cs project:service:roll CLI command, where you can select project, environment where will be applied changes, service and version.
Select latest version if you need a latest available service version.
To rollback service version use the same command cs project:service:roll and just select needed version and environment where to deploy needed version.
A short guide explaining the whole code.store in a single page. Don't say thanks! 👊
The service you are building is going to be consumed by your clients (real clients or frontend teammates) via an API (GraphQL), which your service is exposing. That is why we believe in the schema-first approach, where you are required to define an API (or a schema) first and then develop a backend that provides data for this schema (as opposed to a code-first approach where the schema is generated from the code you write). GraphQL schema (or API) IS YOUR PRODUCT! That is why everything starts with a schema at code.store.
We strive to simplify your life, and so we are taking the complexity of database management from your shoulders and are g automatically from your schema. Whenever you add a new type, field, or modify the existing ones, our platform generates migrations and which you can use to write business logic in resolvers.
When ready, push your changes to our cloud using the to our platform. code.store will check your code, containerize it, and deploy it to a private . You can then promote your service to the Demo environment, which is used to let every developer in your experiment with your and check if it corresponds to the needs of their .
Once created, your cannot be used per se in a production application or site, you need to add it to a . Projects represent applications or sites where your is used. Each service can be used in as many projects as you wish. You can use our web UI or to add your service to any of your projects. Every developer in your organization can create projects and add services to them. A is created when you add a service to a . It's an entirely isolated version of your service: it has its dedicated environments, database, and logs.
For each in a , you can define a rate-plan so that you can bill your clients monthly per service usage (price per call) or as a subscription. The core idea is to bundle together costs of building the service, its maintenance, support, and hosting in a single simple fee that your client pays. Up to today, you can sell and bill services to your clients only, but we'll be launching a public marketplace as soon as we have enough on-board service .
In order to secure public access to API of your projects and services - code.store platform allows you to restrict access using the request authorization mechanism and using access key
code.store platform provides an ability to restrict access using access keys, which serve to identify each request that is sent to your services. Access keys are generated by default when a service or project is created. Also, you can create new access keys for the purpose of separating access for clients manually.
To authenticate your request just add a HEADER “x-user-authorization” to each request, where value of this header will be access key, which you can receive using cs service:info CLI command on the private environment or generate a new one using cs project:client:add command.
Below an example of authorization using curl command in your terminal:
Each service at the beginning is deployed in demo and private environment. But, there are different way to access your service.
Demo environment is always public and can be accessed by any platform user.
private environment - it's a private space, where developer can personally run and test his code. In order to restrict access to the development process, a developer key key was created.
After service creation, you receive a developer key for your private environment. This key must be used each time when you call your service in a private environment.
If you forget your service developer key - execute cs service:info CLI command, select required service (or just navigate to service directory) and you will find it there.
By default, when you create a new project - you receive a project developer key. Using this key you can access any service deployed into your project on any environment. If you forget your project developer key - execute cs project:info CLI command, select required project and you will find it there.
There are cases when it is necessary to provide to the whole project or included in the project services to the client or third party person. code.store platform provides and CLI interface, which allows to manage client's access keys.
Using cs project:client CLI command you can add, list or remove client's access keys for your project and project services.
Clients access keys has a restriction: using this key client can access only production environment. staging and development environments is available only using developer key.
To create a new client access key just execute cs project:client:add command, select the required project from the list and specify client's email
To list client access keys execute cs project:client:list command, select project form the list below and enjoy your client's list:
To revoke client access you should remove client access key using cs project:client:remove command with CLIENT_ID flag.
You'll find all the answers you were looking for since you were born. TL;DR> 42.
code.store is cloud-agnostic, meaning we can deploy code.store on any cloud provider or even on-premises for Enterprise clients.
Services of all other plans are currently hosted on our AWS infrastructure (Frankfurt region at the moment, other regions are coming soon).
You do it. Don't be lazy. 😈
There is no public marketplace yet. When you build new projects for your clients, you can create some part of those as reusable . Then you can sell them to your clients with a subscription or pay-per-use rate plan.
When you add a in a , you can set up a different price for each of your . You can then invite your client to this , providing his billing details. We'll generate the invoice for each client and collect payments for you. Each month you'll receive your combined funds collected from all clients in a single payment from us. Money time!
You can bundle in a single monthly rate everything:
your initial build cost (example: the 50 working days used to build the service)
support and maintenance time (example: the 5 working days you spend every month on this service)
hosting (code.store costs)
At the moment we support only (which is the 2nd most loved programming language in the world 🤘 as per ). If you need a specific language for your , drop us a word .
We provide a managed Postgres database for your services, but you don't have to worry about it as code.store creates and updates your based on the of your .
We call a service piece of code running on our platform that is accessed through a GraphQL API. You can learn more about our core concepts here.
We provide a platform to create and host back-end services that are accessed through GraphQL API. So at the moment, we are not focused on this particular feature, especially knowing that there are already many great services that can help host your frontend in the cloud.
However, this is something that is in our roadmap, and you can to help us prioritize it!
Each service has a default configuration file, which available by default, after new service creation. This configuration file named codestore.yaml and located in the root of service dir.
This file contains service configuration and used to:
enable/disable PostgreSQL database
enable/disable Redis database
setup configuration for local development
contains internal code.store's serviceId
serviceId internal code.store's service id
serviceConfiguration remote service configuration, which allows and contains the following flags:
skipDatabase (false by default) boolean flag, allows to enable or disable PostgreSQL database
enableRedis (false by default) boolean flag, allows to enable or disable Redis database
localConfiguration configuration, which allows to run local development service using cs dev CLI command and. Local configuration contains service, database (Redis, PostgreSQL) configurations which required if databases in serviceConfiguration are enabled. localConfiguration is contains the following properties:
application
port a port where an application will runs
database PostgreSQL connection config
By default, PostgreSQL - enabled. To disable PostgreSQL set skipDatabase: true of the serviceConfigurationobject and push changes using cs push command.
By default, Redis - disabled. To enable Redis set enableRedis: true of the serviceConfigurationobject and push changes using cs push command.
From time to time becomes necessary to monitor the status and progress of a deployed application, look at the current application activity, or debug an error.
code.store platform provides an interface for working with report logs. By default logs contain information about the exceptions that the deployed application produces, service bootstrap and other things that the developer considered necessary to add as logs.
On backstage, as a log storage code.store platform used database, which allows to organize a quick search through the logs.
Environments are created for those cases when it is necessary to create a set of independent services, with own databases, which interacted with each other, in order to isolate the environment for development, testing, and release of service groups.
In service deployment, environments are a kind of isolation medium. Each environment unites certain sets of rules which describe components that it includes, namely: services, their versions, databases, routing traffic rules...
For convenience, we on the code.store platform creates several environments at once for the purpose of comfortable development and rolling out updates.
code.store CLI provides a set of commands that allow you to manage your services and projects. This section contains the installation steps, a typical workflow and a description of main commands.
port port, where Postgres server launched, usually it's 5432
username your Postgres user
password password for your Postgres user
host PostgreSQL host (for example localhost or 127.0.0.0)
database name of the database
environment
version
development
0.0.3
staging
0.0.2
production
0.0.2
Each time, when you develop your application you should carry about your data layer - the place, where database entities, migrations, seeds... are defined. code.store shared developers pain and provide amazing ability automatically generate TypeORM entities and SQL migrations for your database.
When you create a new type or input for your query or mutation inside schema.graphql, which located in your src service directory, or make changes to already existed types you should make changes inside your data models and think about migrations... You don't have to do it each time, code.store platform provides cs generate:models CLI command, which allows to do whole magic for you!
Models and migrations are powerful tool, which allows you to generate complex things. Generator supports different types and relations such as one-to-one, one-to-many, many-to-many...
First of all, you should define your types in schema.graphql, which located in src directory of your service. For example, let's define a simple type Post with some fields:
After schema.graphql modification execute cs generate:models CLI command, which will trigger generation process. During command execution schema.graphql file will upload to code.store's generator. code.store's generator will validate this schema, generate TypeORM entities and migrations and save it on your local machine on src/generatedData folder:
generatedData/ includes two directories:
entities/ dir with your TypeORM entities
migrations/ dir with SQL migrations
code.store's generator allows you to generate models and migrations both for service which already has models and migrations and for an empty project, where you just define your GraphQL schema.
For Post type generated next migration in src/generatedData/migrations/Migration1606769241856.ts file:
There are two methods you must fill with your migration code: up and down. up has to contain the code you need to perform the migration. down has to revert whatever up changed. down method is used to revert the last migration. To learn more about TypeORM migrations visit TypeORM migrations page.
Also, you can find a TypeORM entity inside generatedData/entities/Post.ts file.
If everything is OK and generated files meet your needs - just copy them to the appropriate directories: src/data/entities and src/data/migrations.
To make sure that generated entity is correct, just execute cs dev CLI command. As a result you can find the Post table inside your database. More information about local launch of your code you can find in local development section.
We recommend use entities and migrations generation as bootstrap feature. Always check the files that are generated to avoid surprises.
Note: logs are stored on the platform for a month.
To reach service logs navigate to your service directory and execute cs service:logs command, or specify service ID using -s flag. Below is an example of listing demo_app service logs, where demo_app is an id of service.
By default, command display only 20 of the most recent log lines, to increase output lines count use -n flag. Below is an example of listing demo_app service logs, where output lines count are set to 1000
To access full project logs you should specify project ID using -p flag.
After command execution logs from all deployed services on all (development, staging, production) environments will be displayed.
To filter environments just specify environment name using -e flag. Below is an example of displaying logs of all deployed services on development environment of my_project project.
Also, you can display service logs from demo and private environment. To display these logs specify environment name using -e and service id using -s flag.
code.store platform read full stdout log and store, you may use any convenient logger. But, to make developers life easier - code.store platform provides a built-in logger, which can be imported from codestore-utils.
Built-in logger provides default method for logging and map each log for future text search. Logger provides default logging methods, such as:
log - informational logs that might make sense to system administrators, and highlight the progress of the application
error - error logs of considerable importance that will prevent normal program execution, but might still allow the application to continue running
warn - potentially harmful situations of interest that indicate potential problems -
debug - information that is diagnostically helpful to people more than to system administrators
verbose - verbose information about any thing which may be useful
By default, any log method consume three params: message, context and data.
message - is a message, which will be logged
context (empty by default) - is a prefix of message, which usually indicated where method was executed (method, or constructor name for example...). This param are .
data (optional) - is an optional object, which will be stringify and append to the message
Example of usage:
An exception to the rule is an error method that has a slightly different signature:
This method usually used to log a handled exception. You can just pass an error object as first argument and logger will format a message to valid format. For example:
This installation method is not recommended as it does not auto-update.
These are available in gzip compression:
PalmOS (just kidding)
To verify that the CLI has been correctly installed, use the codestore --version command:
You should see "codestore x.y.z darwin-X node-vX.Y.Z" output.
The code.store CLI will keep itself up to date automatically, unless you installed it via npm install. In that case use npm update codestore in order to upgrade the package to the latest version.
For each service, the code.store CLI is generating a directory structure that resembles the following:
Read more about the anatomy of the service directory here.
> cs service:info
Private Demo
version 0.0.2 0.0.1
deployed 8/5/2020, 10:37:21 PM 8/5/2020, 10:38:58 PM
developer key null
url https://api.code.store/a6203d238a744492bf1bf33833c3ebf6/graphql https://api.code.store/a858e12ddd2c47f5b381bef9d98dc7a9/graphql > cs project:service:info
Development Staging Production
version 0.0.3 0.0.2 0.0.2
deployed 8/5/2020, 10:39:22 PM 8/5/2020, 10:39:23 PM 8/5/2020, 10:39:21 PM
developer key
url https://api.code.store/8ddc603ea9dd4a669755bf2125bdca24/graphql https://api.code.store/bb2eae903e924bdeb3f6fe9627055d93/graphql https://api.code.store/efe4caaf5584497599728f3785e8fc7d/graphql cs promotecs project:service:promotecs project:service:rollcurl \
-X POST \
-H "x-user-authorization: DEFINE_YOUR_ACCESS_KEY_HERE" \
--data 'your GraphQL query' \
https://api.code.store/{service_url_hash}/graphql> cs service:info
version 0.0.1 0.0.1
deployed 11/17/2020, 4:05:27 PM 11/17/2020, 4:14:58 PM
developer key cff7f0fb-8856-48e7-817b-0d83c696b247
url https://api.code.store/{SERVICE_HASH}/graphql https://api.code.store/{SERVICE_HASH}/graphql > cs project:info
Project ID: YOUR_PROJECT_ID
Status: ACTIVE
Services: 1
Developer Key: YOUR_PROJECT_KEY
Author: [email protected]> cs project:client:add
Email: [email protected]
Key: YOUR_CLIENT_KEY> cs project:client:list
Client ID Key Email
1 YOUR_CLIENT_KEY [email protected]> cs project:client:remove --CLIENT_ID 1
Client access key successfully removed!type Post {
id: ID!
createdAt: String!
title: String!
body: String!
authorName: String!
}> cs generate:models
✔ Reading the service schema
✔ Uploading the service schema to the generator
✔ Generated code has been saved to ...demo_app/generatedData import {MigrationInterface, QueryRunner} from "typeorm";
export class Migration1606769241856 implements MigrationInterface {
name = 'Migration1606769241856'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "Post" ("id" BIGSERIAL NOT NULL, "createdAt" varchar NOT NULL, "title" varchar NOT NULL, "body" varchar NOT NULL, "authorName" varchar NOT NULL, CONSTRAINT "PK_c4d3b3dcd73db0b0129ea829f9f" PRIMARY KEY ("id"))`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`DROP TABLE "Post"`, undefined);
}
}import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity('Post')
export default class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
createdAt: string;
@Column()
title: string;
@Column()
body: string;
@Column()
authorName: string;
}
> cs logs -s demo_app
Displaying logs for environment private, service demo_app
2020-11-17T14:02:49.243Z [GqlLoader] Loaded queries: helloWorld
2020-11-17T14:02:49.338Z [RestLoader] Loaded REST handlers:
2020-11-17T14:02:49.341Z [RestLoader] -> /name - GET
2020-11-17T14:02:49.341Z [Bootstrap] -> [GET] http://localhost:3002/rest/name
2020-11-17T14:02:49.341Z [Bootstrap] REST endpoints are available on:
2020-11-17T14:02:49.341Z [Bootstrap] GraphQL is available on: http://localhost:3002/graphql> cs logs -s demo_app -n 1000> cs logs -p my_project> cs logs -p my_project -e development> cs logs -s demo_app -e demoimport { logger } from 'codestore-utils';public log(message: any, context = '', data?: any): void
public warn(message: any, context = '', data?: any): void
public debug(message: any, context = '', data?: any): void
public verbose(message: any, context = '', data?: any): voidimport { logger } from 'codestore-utils';
logger.log('User received a new achievement', `${this.constructor.name}`, { achievement: { name: 'STAR', level: 3 }});public error(error: string | Error, trace = '', context = '', data?: any): voidimport { logger } from 'codestore-utils';
try {
throw new Error('This is an error...');
} catch(e) {
logger.error(e);
}
brew tap code-store-platform/brew && brew install codestorenpm install -g codestorecodestore --version# Example of the directory structure of a Service
./
├── src/
│ ├── data/ # contains generated TypeORM entities
│ ├── resolvers/
│ │ ├── mutations/
│ │ └── mutationExample.js|ts
│ │ ├── queries/
│ │ └── queryExample.js|ts
│ └── schema.graphql # GraphQL definition of your service's API
├── .build # temporary directory
├── package.json # standard NPM configuration file
└── codestore.yaml # main configuration fileThese environments are completely isolated from each other and are separate namespaces in our k8s cluster. When we include a new service in the project, we deploy a copy of a container with different databases in all three environments.
In case when we create a new service, we deploy it on its own, isolated environments - private and demo (hereinafter: Service Environments)
When we create a new service, it is automatically deployed in two environments, which called: private and demo.
A private environment - serves to enable an opportunity to update service and test the changes made in an isolated environment. The API of this service is accessed using a key that is generated when the service is created. Access to services, which deployed in this environment, has only the owner (developer) of this service.
demo environment - serves to publish changes, after the active development process, from a private environment. demo environment - serves as a starting point for distributing the service, or its new versions, to other projects. demo environment is a public environment, where any person who has a link - can access service without any authorization.
You don't have to worry about creating any environment when creating a new project - code.store platform does it for you automatically.
More details on how to create a new service can be found in Projects section. Information on how to deploy updates from private to demo environment is in the Versioning section.
Developer, after new service creation, may test it and roll updates using cs push command on the private environment.
When changes were made and ready to publish - a new service version can be rolled up to demo environment using cs promote command.
After promotion service to demo environment - a new version becomes publicly available. "Public" version - is an exact version, which will be rolled, when you include a new service in the project.
For services deployed on demo and private environments, a set of restrictions and rules apply. These services do not scale under load and available only when requested.
private and demo environments are created only for the purpose of developing service, demonstrating their functionality, and acts as a point for distributing updates.
In a micro-service architecture, deployment approaches are different, but in general, environments start with development and production environments.
We understand how important testing and pre-release preparation for projects and added a staging environment. So, each project on the code.store platform includes the following environments:
development
staging
production
development and staging environments have some limitations in terms of scaling and intended for active development and testing.
production environment has a specific set of rules for scalability and availability. We guarantee SLA (Service Level Agreement) 99.9% of the services deployed to the production environment.
You don't have to worry about creating any environment when creating a new project - the code.store platform does it automatically.
For more information on how to create a project, how to include or exclude a service from a project, see the Projects section.
Managing sensitive strings such as passwords, API keys, and secret credentials — is just one of the steps in the quest for increasing security in a project. We understand this like no one else and provide an extremely easy and secure way of managing secret variables.
All secret variables are stored in Vault, secret storage from HashiCorp organization, which provides a high-security level thanks to its architecture and secret engines.
For convenience, all variables that we specify for the service are available as environment variables. In order to add a new variable for the service, you can use the CLI interface, which can be found in .
Service secrets are secure key-value storage, which syntax is available using cs secret command.
To add a new secret variable just execute cs secret:add command with flags which next flags:
-k key of the secret variable
-v value of the secret variable
-s service ID
Information about all supported flags can be found on section.
Below is an example of adding the FOO variable with the BAR value to the existing service with ID: MY_SERVICE. For clarity, we will use a service that is deployed in a demo environment.
Successful result of the command execution will be:
That’s it! Now, variable FOO will be available as an environment variable after container reboot. Now, you can access it in your code.
For example, to access variable using TypeScript use process global variable:
Using the same command syntax we can add an environment variable for any project services.
-p flag allows adding a variable on the project level.
The FOO variable is now available inside the MY_SERVICE service, which is included in the MY_PROJECT project.
Please note: MY_SERVICE service is already included in MY_PROJECT project.
But what if my project includes many services that are deployed in different environments? Would be inconvenient to prescribe a separate set of secret variables for each service, so we implemented inheritance.
There are cases when we need to specify only one secret variable for all services which includes in the whole project. In this case, we can just execute cs secret:add only with -p project flag.
Let's imagine that we have an empty project with ID: MY_PROJECT, which includes three services with ID's: A, B, and C. They, by default, deployed on three project environments: development, staging, production. For more information about environments, see the section.
Let’s add variable FOO with value BAR to project MY_PROJECT, which will be available for each service on each environment inside MY_PROJECT project.
Successful result of the command execution will be:
As you can see, the Source of a variable - is a project, where we just added a new variable. From this moment, we can access FOO variable from each service, in each environment, which included in our project. In the diagram below, the services that have access to the value of the FOO variable are highlighted in green:
We may face a case when you need a different secret variable value on some service or on the whole environment. This isn't a problem, cause we can just override the value of the variable, using the same cs secret:add command, specifying for which environment/or service we should apply it.
For example, if we specify the FOO variable with value BAR2 for a project MY_PROJECT from the previous example and just set flag -e (environment) with value development, we override this value for each service in the development environment.
Successful result of the command execution will be:
In this case, the Source displays the current variable source and shows that FOO variable has BAR2 value for each service, WHICH includes in the project MY_PROJECT, and deployed on the development environment. In the diagram below, the services that have access to the new value BAR2 of the FOO variable are highlighted in blue:
In case, when our service requires another secret variable value - we can just override it. To override it - just specify -s flag with service ID, let it be service A for example, and a new value of FOO variable is BAR3.
Successful result of the command execution will be:
In this case, service A will obtain a new value of FOO variable. In the diagram below, the services that have access to the new value BAR3 of the FOO variable are highlighted in yellow:
A quick guide to get you onboard with GraphQL
When you create a service on code.store, it is accessible via a unique API endpoint and you'll need to use GraphQL in order to interact with this endpoint.
While you'll find all the details on GraphQL site, we've prepared you a short summary of GraphQL basics here.
You can think of GraphQL as of SQL but for API (it is a very loose and far-fetched analogy, but it should deliver the message).
GraphQL is an API standard that provides a more efficient, powerful and flexible alternative to REST. It was developed and open-sourced by Facebook but now many companies, including us, support and rely on GraphQL. We do think it will become worldwide API standard very soon.
code.store GraphQL service is created by defining types and fields on those types, then providing resolvers for those types.
GraphQL has its own type system that’s used to define the schema of an API. The syntax for writing schemas is called (SDL).
Here is an example how we can use the SDL to define a simple type called Product:
There are 5 built-in scalar types with GraphQL: Int, Float, String, Boolean and ID. Scalar types, as opposed to object types, point to actual data. The ID type resolves to a string, but expects a unique value.
Enumeration types allow to define a specific subset of possible values for a type. In the previous example, the Category enum type can take a value of Clothes, Shoes or Watches and anything else will result in a validation error. We need to update our example providing definition of our enumeration category :
Modifiers can be used on the type that a field resolves to, by using characters like ! and […]. Here’s a breakdown, using the String scalar type as an example:
String: nullable string (the resolved value can be null)
String!: Non-nullable string (if the resolved value is null, an error will be raised)
[String]: Nullable list of nullable string values. The entire value can be null, or specific list elements can be null.
GraphQL doesn’t just specify a way to describe schemas and a query language to retrieve data from those schemas, but an actual execution algorithm for how those queries are transformed into results. This algorithm is quite simple at its core: the query is traversed field by field, executing “resolvers” for each field.
The payload of a GraphQL query (or mutation) consists of a set of fields. In code.store, each of these fields actually corresponds to exactly one service that’s called a resolver. The sole purpose of a resolver function is to fetch the data for its field.
When code.store receives a query, it will call all the functions for the fields that are specified in the query’s payload. It thus resolves the query and is able to retrieve the correct data for each field. Once all resolvers returned, the server will package data up in the format that was described by the query and send it back to the client.
Queries as mutations are the methods or functions of your API. Both have arguments and can return scalars or objects. The difference between the two?
Use queries to query data from your API. With query, you do not modify your model (even if you can, you should not).
Use mutations to update or create things in your service model. Mutations are also methods or functions of your API and can accept arguments. Use them to modify your model.
A mutation can contain multiple fields, just like a query. There's one important distinction between queries and mutations, other than the name:
While query fields are executed in parallel, mutation fields run in series, one after the other.
This means that if we send two incrementCredits mutations in one request, the first is guaranteed to finish before the second begins, ensuring that we don't end up with a race condition with ourselves.
code.store platform supports GraphQL and allows you to set up your GraphQL API in the quickest way. To make a developer's life easier code.store platform:
by default runs GraphQL Apollo Server
provides an opportunity to generate database entities based on graphql.schema
generate resolvers for your queries and mutations
secure your GraphQL API from massive complex requests and DDoS attacks, and allows you to configure GraphQL query costs
Basic information about GraphQL can be found in section.
By default, code.store platform runs and GraphQL playground available via /graphql endpoint.
Local development:
Remote address:
When you create a new service, we code.store platform generating it with default schema.graphql file, which contains services GraphQL schema. You can find it in src directory of the generated project. Generated file contains a simple helloWorld query:
It's a very basic schema of an API that has a single Query called helloWorld (which doesn't accept arguments) and which returns a single output of type string. You can query it using GraphQL playground, which available on /graphql endpoint or execute next command using CLI:
Please, replace service_url_hash on your service URL hash, which can be found after cs service:info command execution. After helloWorld query execution we should get "Hello, World!" response in our terminal:
Each field, query or mutation, which we specify in schema.graphql require resolver. A resolver is a function that's responsible for populating the data for a single field in your schema.
Handler for all queries and mutations, which described in schema.graphql file should be placed to src/resolvers directory. Each resolver file of your query or mutation should be named the same, as it declared in graphql.schema and placed the appropriate directory src/resolvers/queries for queries and src/resolvers/mutations for mutations.
For example, in generated service template you can find, that query helloWorld in schema.graphql have resolver src/resolvers/queries/helloWorld.ts
Each resolver can optionally accept four positional arguments:
parent returns value of the previous resolver in the resolver chain for this field's parent
args an object that contains all GraphQL arguments provided for this field. For example, when executing a query: query{ user(id: "4") }, the args object passed to the user resolver is { "id": "4" }.
context an object shared across all resolvers that are executing for a particular operation and has ResolverContext type.
As you can see, context allows receiving database connection and provide access to request object, which includes such objects as headers, method, url...
info contains information about the operation's execution state, including the field name, the path to the field from the root, and more.

Based on standards for building a microservice architecture, we follow database-per-service design pattern and generate separate database for each service.
code.store platform by default creates a Postgres database for each your service. You can enable or disable database using codestore.yaml configuration file in the root service directory.
You have no limits in your database and can store any data there, code.store platform takes care of the scaling of your relational database so your database can keep up with the increasing demands of your application or applications.
To disable or enable Postgres database for your service just set it in skipDatabase flag.
true - to disable Postgres database
false (default value) - to enable it
You can find connection to your database in context variable which available inside each handler method. More information about context objects can be found in GraphQL and REST sections.
To disable or enable Redis database for your service just set it in enableRedis flag.
true - to enable Redis database
false (default value) - to disable it
You have no limits in your Redis database and can store any data there, code.store platform takes care of the scaling of memory usage so your database can keep up with the increasing demands of your application or applications.
To get credentials for Redis database use next env variables:
REDIS_HOST
REDIS_PORT
More information about accessing environment variables can be found in Environment variables section.
http://localhost:3000/graphql https://api.code.store/{service_url_hash}/graphqltype Query {
helloWorld: String!
}curl \
-X POST \
-H "Content-Type: application/json" \
--data '{ "query": "{ helloWorld }" }' \
https://api.code.store/{service_url_hash}/graphql{"data":{"helloWorld":"Hello, World!"}}import { logger, Resolver } from 'codestore-utils';
const resolver: Resolver = async (parent, args, context, info) => {
logger.log('This is a helloWorld resolver!', 'helloWorld');
return 'Hello, World!';
};
export default resolver;
export interface ResolverContext {
db: {
connection: Connection;
};
request: Request;
[key: string]: any;
}serviceConfiguration:
skipDatabase: trueserviceConfiguration:
enableRedis: true-e service environment
[String!]: Nullable list of non-nullable string values. Then entire value can be null, but specific list elements cannot be null.
[String!]!: Non-nullable list of non-nullable string values. Nothing can be null, neither the whole value nor the individual items.
Projects are the essence of the code.store platform, which has the ability to contain many services.
Projects serve as an isolated environment for services groups. Any project can contain one or more services, and available within the organization the user belongs to.
In order for the service to be publicly available, it must be included in the project, since the code.store platform guarantees high availability and scalability only in a production environment. For more information about environments, see the Environments section.
In order to create a new project, you need to execute cs project:create command and provide information about your service. Below an example of cs project:create command execution:
Successful result of the command execution will be:
After successful project creation, an access key to the development and staging environments will be issued in the command output. Information about authorization using the provided key can be found in section.
When creating a new project, by default, the code.store platform will create three environments: development, staging, and production. For more information about environments, see the section.
Let's make sure that the project has been created by running the cs project:list command.
Project ID displays ids of all projects that available for user. Please, note, that ID is lowercase.
Services count of included to project services.
Author email of the project creator.
Description description, which user set, when creating a project.
After creating a project, it will be available to all members of the organization to which the user belongs.
By default, there are no services in the project. To add a new service to the project just execute cs project:service:add command with two arguments: projectID - where service should be included and serviceID - id of service, which will be included.
For example, let's include service demo_app to the my_project project:
After command execution, the service is being to deploy to the development project environment.
To monitor service deployment status just execute cs project:service:info command and select the project and service.
cs project:service:info command output will display environments, where service is deployed (in our case service just added to project and deployed only to development environment), deployed service version, developer key, and the service URL.
After adding a new service to the project, it becomes necessary to deploy it not only to development but also to staging and production environments.
To promote service per environments available cs project:service:promote command. After command execution, you will be able to select the project, service which already included into the selected project and environment, where service should be deployed.
In the example above, we promote service with ID: demo_app, which already included to project with ID: my_project to the staging environment.
Using this approach, you can deploy the service to a production environment.
To update service version just re-use cs project:service:promote command.
It is necessary that the service was previously updated on the demo environment. For more information about environments, see the section. About versioning see the section.
cs secret:add -s MY_SERVICE -e demo -k FOO -v BARSuccessfully added a new secret variable FOO
Key Value Source
FOO BAR Environment: demo, ServiceID: 1 process.env.FOOcs secret:add -p MY_PROJECT -s MY_SERVICE -e development -k FOO -v BARcs secret:add -p MY_PROJECT -k FOO -v BARSuccessfully added a new secret variable FOO
Key Value Source
FOO BAR ProjectID: 1 cs secret:add -p MY_PROJECT -e development -k FOO -v BAR2Successfully added a new secret variable FOO
Key Value Source
FOO BAR2 ProjectID: 1, Environment: development cs secret:add -p MY_PROJECT -e development -s A -k FOO -v BAR3Successfully added a new secret variable FOO
Key Value Source
FOO BAR3 ProjectID: 1, Environment: development, ServiceID: 1 type Product {
title: String!
SKU: ID!
descirption: String!
price: Float!
stock: Int!
category: Category!
}enum Category {
Clothes
Shoes
Watches
}
type Product {
title: String!
SKU: ID!
descirption: String!
price: Float!
stock: Int!
category: Category!
}
This page is all about definitions and vocabulary to get you on board as fast as possible.
Service is the most crucial concept in code.store. It is a stand-alone web-service that can be (re)used in projects. What defines a service:
GraphQL Schema: you start by defining a GraphQL API describing types, queries and mutations of your service
Code: actual code that is invoked when your GraphQL API is called. There is a specific structure and naming convention for your files which we describe in our Quick Start guide.
Database: based on your GraphQL schema, there is a where you can store your data. We take care of its creation, updates and whole management including automatic migrations in case of any change in your .
Documentation: when you create a new service you need to explain what functional problem your service solves, how does it solve it and what is its functional domain (e-commerce, content management, logistics, etc.). You can also add some free #tags to help users search for your service.
What makes a perfect code.store service :
Independent: it does not rely on anything else to function (no external APIs or services or software is required to use it).
Isolated: by all means, it should avoid communication with external systems (except for connectors)
Autonomous: it's shipped with a database and file storage if any of those are required.
Some examples of what we call service :
Shopping cart of an e-commerce site
Meeting rooms booking system
Email sending service
Credit card payment
Each service has 2 : private - used by service for their development and tests, and demo, used by developers to test the service
A project is a particular app or website, where you reuse your existing services. It might be your e-commerce project or a logistics mobile application or business web-app. Because you pay us only when we help you save money, we bill you only for live (those that are included in Projects).
Each time you add a service to a project, we create a separate, isolated instance of your . Each service reused in a project has its own , , logs, and billing.
A service reused in a is an instance of a you've created. Each time you add a service to a project, you create a service instance. Each instance of a service is isolated, runs its own set of 3 (dev, stage, prod) and is accessible through its GraphQL .
A schema or defines and describes your . It uses with some additional directives. You have to define 3 main things:
: they describe objects your service is manipulating (Product for a cart, Meeting Room for rooms booking engine or Client for a CRM service).
: at its simplest, GraphQL is about asking for specific fields on objects. It's a shorthand syntax where we omit both the query keyword and the query name, but in production apps, it's useful to use these to make our code less ambiguous.
Mutations: most discussions of GraphQL focus on data fetching, but any complete data platform needs a way to modify server-side data as well. So mutations offer your API consumers a way to create and update objects manipulated by your service (i.e., addToCart(productSKU))
A model is a description of the way your service's database is structured. You cannot directly modify your service's model, which is generated based on the GraphQL schema of your service. We generate TypeORM entities in your service files directories here: /src/models/
You can access the structure of your database or model through the web-UI data viewer too.
Each has a managed database related to its . Each time you add, remove or update a type or a field, we automatically update and migrate your service's database. We use PostgreSQL to run your service's database, and we generate TypeORM entities to help you access your data from your service's code. You can also access your database, through ou data viewer web-UI.
An environment is an isolated, running copy of your service. Your is automatically shipped with 2 environments: private and demo. Private is visible only to you, the service , while demo is used to test the service by anyone in your willing to use it on their . It's also demo environment which is used in web-UI service page where users within your can use the playground to experiment with your service.
As soon as you reuse a in a , you create a and 3 environments for this particular service in this particular : dev, stage and prod. Each environment has its own , , logs and other stuff. Be careful though, only prod environment is suitable to be used, well... in production, others (dev, stage, private, demo) have quotas and limitations and are not scalable.
Of course, you are not obliged to use any of those environments, and you can push your service to prod as soon as it's ready. However, first of all, it is not considered to be a good practice, and secondly, you may want to match the environment of your service with that of your front-end.
If you read this documentation, you're a developer. We needed to distinguish developers who create from those who use them in . It's not a role or hard distinction, and you can be both consumer and maker of services within your . So to make it clear, we call maker the developer who created a .
When you enable billing on your , you're prompted to invite a client to your . So on code.store, a client is an who pays for used in a project. It's entirely optional to have clients. If you don't sell your services and use them internally, you will not need to deal with clients.
It's an entity where projects, services and users are attached to. All services you create as a maker are visible to all users within your organization. Each user of code.store is always attached to an organization.
It's the URL you need to call to connect to your and execute queries. There is an endpoint for each of your . There are endpoints used to test a service before using it (private and demo attached to each service created by your ), and there are 3 endpoints for each inside each : dev, stage and prod.

At the moment, code.store's platform supports a simple file-system-based routing of REST API endpoints.
REST endpoints are based on framework, so you can use all Express features to build your application. Using REST-based on you are able to create endpoints of different methods (such as GET, POST, PUT, DELETE, PATH…), define your route paths, handlers, work with route parameters, define your middlewares…
code.store platform simplifies the process of creating endpoints and their handlers using flexible configuration and provides an ability to generate a couple of entities.
> cs project:create
What is your project's name?
Name: MY_PROJECT
Please add a short description of your project. 255 chars max
Description: This is my project.
? Is everything ok, can I create this project? (Y/n) Y
⠦ Creating Project "MY_PROJECT" ✔ Your project "MY_PROJECT" with ID my_project has been created!
› You can now add your services there using codestore project:service:add command.
Use your developer key to access developer and stage environments: bb9c2512-3d4c-4e57-8dfa-99eafc1484c8 Project ID Services Author Description
my_project 0 [email protected] This is my project. > cs project:service:add my_project demo_app
Would you like to enable billing for your service?
Enable billing: No
✔ Service demo_app is included to project my_project
Status: DEPLOYMENT_INITIALIZING
> cs project:service:info
Choose which project you want to display information about
Project: my_project
Choose which service you want to display information about
Service: demo_app
Development
version 0.0.1
deployed 11/17/2020, 12:15:02 PM
developer key
url https://api.code.store/8e7bf7e43f63414c9f7fc8d7fe7d0410/graphql > cs project:service:promote
Choose a project you want to promote to
Project: my_project
Choose a service which you want to promote
Service: demo_app
? Please select the environment staging
Updated "staging" in project my_project
> cs project:service:promote
Choose a project you want to promote to
Project: my_project
Choose a service which you want to promote
Service: demo_app
? Please select the environment development
Updated "development" in project my_project
Accessible only through GraphQL: yes, the only way to access your service and its data, is through its GraphQL API.
Promotions code management for an e-commerce site
Client view service presenting complete information about a client gathering parts from SAP, Magento and Salesforce.

code.store platform exposes the http://{your service url}/rest/{endpoint} route, where {endpoint} is getting routed to the file ./src/rest/{http method}.{endpoint}.ts.
In order to create an endpoint, you need to create a new file in the src/rest folder (by default, no such directory exists) the name of which will contain the request method (GET, POST, PUT, DELETE ...) at the beginning of the name and the name of the route. For example:
request GET http://localhost:3000/rest/helloWorld will be routed to src/rest/get.helloWorld.ts
request POST http://localhost:3000/rest/user/create will get routed to src/rest/post.user.create.ts
Each newly created endpoint file must export a function that contains the business logic. Exported function takes two arguments: event and context, which contains a connection to the database and mapped request object. Each handler may release any business logic you need. You can import any library, connect to the database, execute queries... Here an example of "hello world" handler:
Handler function takes two arguments: event and context.
event - is an object, which provides mapped request objects. Query params, request body, request headers can be accessed here. Below you can find an interface of event object:
In cases, when params, body and headers are not enough to implement you can access req and res object. REST endpoints are based on Express framework and allow you to use all features of this framework. event object exposes request and response objects, which are Express objects and can be used in the handler as you wish.
The next POST request curl -X POST 'http://localhost:3000/rest/helloWorld?hello=world' --data '{ "test": "object" }' -H "Content-Type: application/json" will result in the following event object:
context - is an object, which provides TypeORM connection object. In case if database is available for your service - you can access it and establish a connection with database.
The context argument contains the database connection property which you can use with your TypeORM entities:
As you can see, the concept is very simple but is very powerful at the same time, as it allows you to create custom REST endpoints, which could be used for integration with OAuth provides, Stripe or other payment systems which require callbacks!
There is no need to use an Express response object to generate a server response, just return string in case if string response is required or return an object, which will be sent as JSON response, following the next interface: