DEV Community

Cover image for Edge, an OpenSource NextJS application with dynamic API for makers and developers.
venture
venture

Posted on

Edge, an OpenSource NextJS application with dynamic API for makers and developers.

During the last months, we have been working on an OpenSource tool called Edge.

Edge offers a full-fledged Nextjs server capable of being deployed in minutes, adapting to your needs, only by changing some configuration options. It offers Dynamic API, dynamic dashboard, basic authentication, and authorization based in Roles, file upload, emails, and much more, all implemented.

Edge can be the foundation for your next MVP or web prototype.

Why Edge?

Edge serves the purpose of being able to prototype a new idea easily.

Some examples:

  • You need to launch a platform for a client with a small budget. And several "boring" things like user authentication, basic API endpoints, static pages, could be resolved for you. Later you can extend edge to adjust to your needs or use it as a stand-alone API.

  • You want to launch a social platform where users can post content: Recipes, Advertisements, Book Reviews, you name it. It is easy with Edge, for your first version. Later on, you maybe need some custom development to adapt it to your needs.

  • You want to launch your own blog, but you don't want to deploy another instance for your CMS. You have a built in dashboard in Edge.

  • You need an content type based API and a landing page for your product in a quick time

What are the features of Edge?

Content

  • Dynamic forms based on content-type definitions. Allowing users to create any kind of content. Just define them on a config file
  • Dynamic API with roles, based on content-type definitions. Easily configure your API to support all the content types your project needs.
  • Dynamic content-views to list all the content and be SEO friendly (with the content slug for the URL, and server-side rendering)
  • Content can be categorized by tags.
  • Web monetization built in for content

Users

  • Possibility to define new user roles or use the standard (ADMIN, USER, PUBLIC).
  • Administration dashboard to block or unblock users.
  • Login and register with social providers. Edge offers integration with Github, Google, and Facebook. It uses passport so it is easy to add many more.
  • Cool user profiles

Files

  • Content can contain files. Edge has integrated code to work with Google Cloud Platform but is easily extendable to different storage providers

Comments

  • Content can have comments. Comments are role-based and can create a conversation between users.

Administration

  • The administration role can access to some dashboards to control content and users.

Dashboard

Themes

Built-in CSS themes Light, Dark, Robot, Edge, Kawaii. Allowing users to change their theme preference.

Themes

React Components

We coded many components that you can find here: https://edge-next.now.sh/components.

Components

Why we didn't use MaterialUI or another component library? We want full control of our developments. We want something we can touch, delete, break, adapt.

Other Features

  • PWA provided by next-pwa
  • Markdown static page rendering. Static content generation with markdown support
  • Markdown dynamic content. Support for markdown in content-types

How do I use Edge, now?

It is really easy, just clone our repository and follow the setup instructions.

Setup instructions:

  • run yarn
  • run yarn dev to start working

You will need to configure the different environment variables (take a look at the documentation ) for configuring all the features (Mongo, storage, social login, etc). But once you create all the keys you need, you will have your site up and running. That's how we deployed Edgechain just in a couple of hours of work!

Some Documentation

Creating new content types

To create a new content type you will need to edit the edge.config.js file and add as many content type definitions as you want.

const contentType = {
  // The name for this content type
  title: 'Blog Posts',

  // The URL for the API and client routes
  slug: 'blog-posts',

  // How slugs are going to be generated for new content. 
  // For example "a-new-blog-post-123132132"
  slugGeneration: ['title', 'createdAt'],

  // Sets of permissions for the API and client sides
  permissions: {
    // Who can read the content
    read: ['PUBLIC'],

    // Who can create content
    create: ['ADMIN', 'USER'],

    // Who can edit ANY content
    update: ['ADMIN'],

    // Who can delete ANY content
    delete: ['ADMIN'],

    // Who can perform all of the above
    admin: ['ADMIN']
  },

  // Publishing and SEO settings
  publishing: {

    // Allow content owners to mark the content as draft and avoid visibility
    draftMode: true,

    // Which field will be used for SEO and linking
    title: 'title'
  },

  monetization: {
    web: true // Enable web monetization for a content type
  },


  // A list of fields, see Edge next documentation for more information
  fields: [{
    // Required values
    name: 'title',
    type: 'text',
    label: 'Post title',

    // Optional values
    placeholder: 'Type your title',
    minlength: 10,
    maxlength: 200,
    required: true,
  }]
}
```

`

### Enabling or disabling comments on content types

Comments are disabled by default. If you want to enable them on a content type just add 
`

```javascript
const postContentType = {
  /* ... previous configuration ... */
  comments: {
    enabled: true
  }
}
```



Then you can fine-tune the permissions:


````javascript
const postContentType = {
  /* ... previous configuration ... */
  comments: {
    enabled: true,
    permissions: {
      read: ['PUBLIC'],
      create: ['ADMIN', 'USER'],
      update: ['ADMIN'],
      delete: ['ADMIN'],
      admin: ['ADMIN'],
    },
  }
}
```
{% endraw %}

Permissions like {% raw %}`update`{% endraw %} and {% raw %}`delete`{% endraw %} imply that the user will be able to edit ANY or delete ANY comment. Any logged user is able to edit or delete it's own comments or comment.

----

## Configuring environment variables


For that, create a file called {% raw %}`.env.local` and add the following code:



```
BASE_URL=http://localhost:3000
MONGODB_URI=MONGODB_URI=mongodb+srv://<username>:<password>@<url>
MONGODB_DATABASE=<database>
SENDGRID_KEY=XXX
FACEBOOK_ID=XX
FACEBOOK_SECRET=XX
GOOGLE_CLIENT_EMAIL=XX
GOOGLE_PRIVATE_KEY=XX
GOOGLE_PROJECTID=XX
GOOGLE_BUCKET_NAME=edge-next
GITHUB_ID=XX
GITHUB_SECRET=XX
GOOGLE_ID=XX
GOOGLE_SECRET
NEXT_PUBLIC_GA_TRACKING_ID=xx
```

`

As you can see here there are many third-party tools and services that are needed to run a full-fledged service. But do not worry, setting up these accounts is something easy and here there are some tips:

- [Register your Github application](https://developer.github.com/v3/guides/basics-of-authentication/)
- [Register your Google application](https://developers.google.com/identity/sign-in/web/sign-in)
- [Register your Facebook application](https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/)
- [Get a sendgrid API key](https://www.youtube.com/watch?v=ShOQxpX7Dcw)
- [Create a Mongo Atlas account](https://docs.mongodb.com/guides/cloud/connectionstring/)
- [Create a Google cloud bucket](https://cloud.google.com/storage/docs/creating-buckets) & [Making files public in google bucket](https://cloud.google.com/storage/docs/access-control/making-data-public)
- [Get a Google Maps API key](https://developers.google.com/maps/documentation/javascript/get-api-key?hl=es-419)

-----

## How can I hack Edge?

Anyway...! You don't need to use all the services listed there. You can just use some of the features Edge offers. Think of Edge (at the moment) like Hackathon Starter on steroids. You can delete or adapt any of it's logic.

## Feedback and contributions

We are looking for people who can share HONEST feedback with us, makes us grow and give value back to the community. 


## API 

This is the API that Edge exposes as of version 1.0

### Auth
- `POST /api/auth/login`
  - `{ email: xxx@xxx.com, password: password}`
  - Logs in a user
- `GET /api/auth/logout`
  - Logout a user
- `GET /api/auth/reset-password?email=xxx@xxx.com`
  - Marks the user for reset password, sends an email with a token
- `POST /api/auth/reset-password`
  - `{email: xxx@xxx.com, password: NewPassword, token: token }`
  - Enables de new password for a user
- `GET /api/auth/verify?email=xxx@xxx.com&token=TOKEN`
  - Verifies a user email

### Users
- `GET /api/users`
  - Access limited to users with permission `user.list` or `user.admin`
- `GET /api/users/ID` | `GET /api/users/me` | `GET /api/users/@username`
  - Access limited to own user or users with permission `user.read` or `user.admin` (or own user)
- `POST /api/users`
  - Access limited to users with permission `user.create`. Default is public, to allow users to register.
- `PUT /api/users/ID`
  - Access limited to own user or users with permission `user.admin` and `user.update`
  - To update a user the different endpoint sufixes have to be added
  - `PUT /api/users/ID/profile`

  - `PUT /api/users/ID/email`

  - `PUT /api/users/ID/username`

  - `PUT /api/users/ID/picture`

  - `PUT /api/users/ID/password`

  - `PUT /api/users/ID/block`

- `DELETE /api/users/ID`
  - Access limited to own user or users with permission `user.admin` and `user.delete`. For the current user is also required to send a `password` query parameter.

### Content
- `GET /api/content/[TYPE]`
  - Access limited to users with permission `content.TYPE.read` or `content.TYPE.admin`
- `GET /api/content/[TYPE]/[CONTENT_SLUG]` | `GET /api/content/[TYPE]/[CONTENT_ID]?field=id`
  - Access limited to own user or users with permission `content.TYPE.read` or `content.TYPE.admin`
- `POST /api/content/[TYPE]`
  - Access limited to `content.TYPE.admin`, or `content.TYPE.create`
- `PUT /api/content/[TYPE]/[CONTENT_SLUG]` | `POST /api/content/[TYPE]/[CONTENT_SLUG]` |  `PUT /api/content/[TYPE]/[CONTENT_ID]?field=id` |  `POST /api/content/[TYPE]/[CONTENT_ID]?field=id`
  - Access limited to own user or users with permission `content.TYPE.admin` or `content.TYPE.update`
- `DELETE /api/content/[TYPE]/[CONTENT_SLUG]` | `GET /api/content/[TYPE]/[CONTENT_ID]?field=id`
  - Access limited to own user or users with permission `content.TYPE.admin` or `content.TYPE.delete`

### Comments

- `GET /api/comments?contentType=CONTENT_TYPE`
  - Access limited to users with permission `content.TYPE.comments.read` or `content.TYPE.comments.admin`. If no CONTENT_TYPE is specified, it will list all the comments that the current user has access to.
  - Other filters available are `contentId`, `author` (user id), `conversationId` (can be set to the string `'false'` to ellicit empty conversationIds)

- `POST /api/comments?contentId=CONTENT_ID&contentType=CONTENT_TYPE`
  - Access limited to `content.TYPE.comments.admin`, or `content.TYPE.comments.create`

- `GET /api/comments/[COMMENT_SLUG]` or `GET /api/comments/[COMMENT_ID]?field=id` 
  - Access limited to own user or users with permission `content.TYPE.comments.read` or `content.TYPE.comments.admin`
- `DELETE /api/comments/[COMMENT_SLUG]` or `DELETE /api/comments/[COMMENT_ID]?field=id` 
  - Access limited to own user or users with permission `content.TYPE.comments.admin` or `content.TYPE.comments.delete`

### Activity

- `GET /api/activity/[USER_ID]`
  - Returns a list of activity for the user, access limited to own user or users with permission `activity.read` or `activity.admin`





I hope some of you get to use Edge and can give us some feedback or collaborate on the open source initiative.

Thanks !


Enter fullscreen mode Exit fullscreen mode

Top comments (17)

Collapse
 
muni profile image
Muni Perez

This is great. I always thought Nodejs missed something like Laravel on PHP.

However, may I ask why you are not using Typescript for the project? I feel like as it scales, Typescript would be essential for maintainability in the long run.

Collapse
 
venture profile image
venture

you are totally right, we may rewrite it with typescript if the community likes it. I am not used to using typescript in my day to day, that's why I didn't use it at the beginning, but maybe is time

Collapse
 
muni profile image
Muni Perez

I see.

I have a lot of experience with TS and would be happy to contribute if you are interested.

Thread Thread
 
venture profile image
venture • Edited

Thanks muni, i will start a branch on the following days to introduce TS and will leave some notification here. I would like to start introducing it gently (not typing everything but the most important parts)

Thread Thread
 
muni profile image
Muni Perez

Great! Please let me know ;)

Thread Thread
 
venture profile image
venture

Hello @muni, this is the branch ts if you want to contribute.
github.com/nucleo-org/edge-next/tr...

I already introduced some typing. Some notes: make PRs to the ts branch, make small changes so we can evaluate if the approach is good. Since we don't want to fully migrate yet to TS until we are sure we are following the best practices

Thread Thread
 
muni profile image
Muni Perez

Great. Will work on it tonight.

Thread Thread
 
muni profile image
Muni Perez • Edited

@rafinskipg , can you add me as a contributor to the repo? My Github user is muniperez

Thread Thread
 
venture profile image
venture

I think you can do a pull request by forking the repository, right? without having the contributor permissions. let me know, please

Thread Thread
 
muni profile image
Muni Perez

Yep worked. Thanks!

Collapse
 
jordansnow_thelegend profile image
Jordan Snow

Just from the description, this looks amazing. I've recently created Next apps using Strapi for the API, I'll be anxious to use this instead and see what benefits come from having the whole thing packaged together. Have you noticed any giant changes in speed when bundling the API with the app like this?

Excited to try this out, thanks for putting up an article here!

Collapse
 
ekafyi profile image
Eka

Whoa. Super powerful. I love Next esp. because its SSR versatility, and this takes Next's awesomeness to the next level. Going to try it when I have the opportunity.

But IMO the name would make it harder to search (eg. Stackoverflow answers, packages, etc) because the results will be mixed with Edge browser topics.

Collapse
 
blindfish3 profile image
Ben Calder

Agreed on the name: you say Edge in a web context and the first thing that springs to mind - and to your search results - is a well known web browser.

Collapse
 
venture profile image
venture

That's good feedback, eka! we will consider changing it! thanks!

Collapse
 
w3bdesign profile image
w3bdesign

There's a 404 error with the documentation.

I have opened a pull request: github.com/nucleo-org/edge-next/pu...

Collapse
 
venture profile image
venture

Thank you! Merged LGTM

Collapse
 
miguefl profile image
Miguel Fernández

Awesome ! It looks great !